@multitenantkit/adapter-persistence-supabase 0.2.1
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 +225 -0
- package/dist/client/SupabaseClient.d.ts +29 -0
- package/dist/client/SupabaseClient.d.ts.map +1 -0
- package/dist/client/SupabaseClient.js +36 -0
- package/dist/client/SupabaseClient.js.map +1 -0
- package/dist/factory/SupabaseFactory.d.ts +45 -0
- package/dist/factory/SupabaseFactory.d.ts.map +1 -0
- package/dist/factory/SupabaseFactory.js +33 -0
- package/dist/factory/SupabaseFactory.js.map +1 -0
- package/dist/factory/UseCaseFactory.d.ts +26 -0
- package/dist/factory/UseCaseFactory.d.ts.map +1 -0
- package/dist/factory/UseCaseFactory.js +76 -0
- package/dist/factory/UseCaseFactory.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/mappers/OrganizationMapper.d.ts +47 -0
- package/dist/mappers/OrganizationMapper.d.ts.map +1 -0
- package/dist/mappers/OrganizationMapper.js +56 -0
- package/dist/mappers/OrganizationMapper.js.map +1 -0
- package/dist/mappers/OrganizationMembershipMapper.d.ts +59 -0
- package/dist/mappers/OrganizationMembershipMapper.d.ts.map +1 -0
- package/dist/mappers/OrganizationMembershipMapper.js +78 -0
- package/dist/mappers/OrganizationMembershipMapper.js.map +1 -0
- package/dist/mappers/UserMapper.d.ts +53 -0
- package/dist/mappers/UserMapper.d.ts.map +1 -0
- package/dist/mappers/UserMapper.js +62 -0
- package/dist/mappers/UserMapper.js.map +1 -0
- package/dist/repositories/SupabaseOrganizationMembershipRepository.d.ts +33 -0
- package/dist/repositories/SupabaseOrganizationMembershipRepository.d.ts.map +1 -0
- package/dist/repositories/SupabaseOrganizationMembershipRepository.js +239 -0
- package/dist/repositories/SupabaseOrganizationMembershipRepository.js.map +1 -0
- package/dist/repositories/SupabaseOrganizationRepository.d.ts +33 -0
- package/dist/repositories/SupabaseOrganizationRepository.d.ts.map +1 -0
- package/dist/repositories/SupabaseOrganizationRepository.js +150 -0
- package/dist/repositories/SupabaseOrganizationRepository.js.map +1 -0
- package/dist/repositories/SupabaseUserRepository.d.ts +60 -0
- package/dist/repositories/SupabaseUserRepository.d.ts.map +1 -0
- package/dist/repositories/SupabaseUserRepository.js +168 -0
- package/dist/repositories/SupabaseUserRepository.js.map +1 -0
- package/dist/system/WebClock.d.ts +17 -0
- package/dist/system/WebClock.d.ts.map +1 -0
- package/dist/system/WebClock.js +18 -0
- package/dist/system/WebClock.js.map +1 -0
- package/dist/system/WebCryptoUuid.d.ts +21 -0
- package/dist/system/WebCryptoUuid.d.ts.map +1 -0
- package/dist/system/WebCryptoUuid.js +22 -0
- package/dist/system/WebCryptoUuid.js.map +1 -0
- package/dist/system/index.d.ts +3 -0
- package/dist/system/index.d.ts.map +1 -0
- package/dist/system/index.js +3 -0
- package/dist/system/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase Organization Repository
|
|
3
|
+
*/
|
|
4
|
+
import type { Organization, OrganizationRepository, ToolkitOptions } from '@multitenantkit/domain-contracts';
|
|
5
|
+
import type { OperationContext } from '@multitenantkit/domain-contracts/shared';
|
|
6
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
7
|
+
/**
|
|
8
|
+
* Supabase implementation of OrganizationRepository
|
|
9
|
+
*/
|
|
10
|
+
export declare class SupabaseOrganizationRepository<TCustomFields = {}> implements OrganizationRepository {
|
|
11
|
+
private readonly client;
|
|
12
|
+
private readonly configHelper;
|
|
13
|
+
private readonly schemaName?;
|
|
14
|
+
private readonly tableName;
|
|
15
|
+
constructor(client: SupabaseClient, toolkitOptions?: ToolkitOptions<unknown, TCustomFields, unknown>);
|
|
16
|
+
private getTable;
|
|
17
|
+
private getSelectColumns;
|
|
18
|
+
private mapToDomain;
|
|
19
|
+
findById(id: string): Promise<(Organization & TCustomFields) | null>;
|
|
20
|
+
findByOwner(ownerUserId: string): Promise<(Organization & TCustomFields)[]>;
|
|
21
|
+
findByIds(ids: string[]): Promise<(Organization & TCustomFields)[]>;
|
|
22
|
+
count(): Promise<number>;
|
|
23
|
+
findMany(options?: {
|
|
24
|
+
limit?: number;
|
|
25
|
+
offset?: number;
|
|
26
|
+
status?: 'active' | 'archived';
|
|
27
|
+
ownerUserId?: string;
|
|
28
|
+
}): Promise<(Organization & TCustomFields)[]>;
|
|
29
|
+
insert(org: Organization & TCustomFields, _context?: OperationContext): Promise<void>;
|
|
30
|
+
update(org: Organization & TCustomFields, _context?: OperationContext): Promise<void>;
|
|
31
|
+
delete(id: string, _context?: OperationContext): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=SupabaseOrganizationRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SupabaseOrganizationRepository.d.ts","sourceRoot":"","sources":["../../src/repositories/SupabaseOrganizationRepository.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACR,YAAY,EACZ,sBAAsB,EACtB,cAAc,EACjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D;;GAEG;AAEH,qBAAa,8BAA8B,CAAC,aAAa,GAAG,EAAE,CAAE,YAAW,sBAAsB;IAMzF,OAAO,CAAC,QAAQ,CAAC,MAAM;IAL3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoD;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGd,MAAM,EAAE,cAAc,EACvC,cAAc,CAAC,EAAE,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC;IAgBpE,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,WAAW;IAUb,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,YAAY,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IAcpE,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC;IAY3E,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC;IAgBnE,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAUxB,QAAQ,CAAC,OAAO,CAAC,EAAE;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,CAAC,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC;IA8BvC,MAAM,CAAC,GAAG,EAAE,YAAY,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBrF,MAAM,CAAC,GAAG,EAAE,YAAY,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BrF,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CASvE"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase Organization Repository
|
|
3
|
+
*/
|
|
4
|
+
import { OrganizationRepositoryConfigHelper } from '@multitenantkit/domain-contracts';
|
|
5
|
+
import { OrganizationMapper } from '../mappers/OrganizationMapper';
|
|
6
|
+
/**
|
|
7
|
+
* Supabase implementation of OrganizationRepository
|
|
8
|
+
*/
|
|
9
|
+
// biome-ignore lint/complexity/noBannedTypes: Empty object {} is the correct default
|
|
10
|
+
export class SupabaseOrganizationRepository {
|
|
11
|
+
client;
|
|
12
|
+
configHelper;
|
|
13
|
+
schemaName;
|
|
14
|
+
tableName;
|
|
15
|
+
constructor(client, toolkitOptions) {
|
|
16
|
+
this.client = client;
|
|
17
|
+
const orgConfig = toolkitOptions?.organizations?.customFields;
|
|
18
|
+
this.schemaName = toolkitOptions?.organizations?.database?.schema;
|
|
19
|
+
this.tableName = toolkitOptions?.organizations?.database?.table || 'organizations';
|
|
20
|
+
const databaseNamingStrategy = toolkitOptions?.organizations?.database?.namingStrategy;
|
|
21
|
+
const globalNamingStrategy = toolkitOptions?.namingStrategy;
|
|
22
|
+
this.configHelper = new OrganizationRepositoryConfigHelper(orgConfig, databaseNamingStrategy, globalNamingStrategy);
|
|
23
|
+
}
|
|
24
|
+
getTable() {
|
|
25
|
+
if (this.schemaName) {
|
|
26
|
+
return this.client.schema(this.schemaName).from(this.tableName);
|
|
27
|
+
}
|
|
28
|
+
return this.client.from(this.tableName);
|
|
29
|
+
}
|
|
30
|
+
getSelectColumns() {
|
|
31
|
+
if (this.configHelper.hasCustomFields) {
|
|
32
|
+
return '*';
|
|
33
|
+
}
|
|
34
|
+
return [
|
|
35
|
+
this.configHelper.getColumnName('id'),
|
|
36
|
+
this.configHelper.getColumnName('ownerUserId'),
|
|
37
|
+
this.configHelper.getColumnName('createdAt'),
|
|
38
|
+
this.configHelper.getColumnName('updatedAt'),
|
|
39
|
+
this.configHelper.getColumnName('deletedAt')
|
|
40
|
+
].join(', ');
|
|
41
|
+
}
|
|
42
|
+
mapToDomain(row) {
|
|
43
|
+
return OrganizationMapper.toDomainWithCustom(row, this.configHelper.columnMap, this.configHelper.hasCustomFields
|
|
44
|
+
? (dbRow) => this.configHelper.customFieldsToDomain(dbRow)
|
|
45
|
+
: undefined);
|
|
46
|
+
}
|
|
47
|
+
async findById(id) {
|
|
48
|
+
const { data, error } = await this.getTable()
|
|
49
|
+
.select(this.getSelectColumns())
|
|
50
|
+
.eq(this.configHelper.getColumnName('id'), id)
|
|
51
|
+
.limit(1)
|
|
52
|
+
.single();
|
|
53
|
+
if (error || !data) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return this.mapToDomain(data);
|
|
57
|
+
}
|
|
58
|
+
async findByOwner(ownerUserId) {
|
|
59
|
+
const { data, error } = await this.getTable()
|
|
60
|
+
.select(this.getSelectColumns())
|
|
61
|
+
.eq(this.configHelper.getColumnName('ownerUserId'), ownerUserId);
|
|
62
|
+
if (error || !data) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
return data.map((row) => this.mapToDomain(row));
|
|
66
|
+
}
|
|
67
|
+
async findByIds(ids) {
|
|
68
|
+
if (ids.length === 0) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const { data, error } = await this.getTable()
|
|
72
|
+
.select(this.getSelectColumns())
|
|
73
|
+
.in(this.configHelper.getColumnName('id'), ids);
|
|
74
|
+
if (error || !data) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
return data.map((row) => this.mapToDomain(row));
|
|
78
|
+
}
|
|
79
|
+
async count() {
|
|
80
|
+
const { count, error } = await this.getTable().select('*', { count: 'exact', head: true });
|
|
81
|
+
if (error) {
|
|
82
|
+
throw new Error(`Failed to count organizations: ${error.message}`);
|
|
83
|
+
}
|
|
84
|
+
return count ?? 0;
|
|
85
|
+
}
|
|
86
|
+
async findMany(options) {
|
|
87
|
+
let query = this.getTable().select(this.getSelectColumns());
|
|
88
|
+
if (options?.ownerUserId) {
|
|
89
|
+
query = query.eq(this.configHelper.getColumnName('ownerUserId'), options.ownerUserId);
|
|
90
|
+
}
|
|
91
|
+
if (options?.status === 'active') {
|
|
92
|
+
query = query.is(this.configHelper.getColumnName('deletedAt'), null);
|
|
93
|
+
}
|
|
94
|
+
else if (options?.status === 'archived') {
|
|
95
|
+
query = query.not(this.configHelper.getColumnName('deletedAt'), 'is', null);
|
|
96
|
+
}
|
|
97
|
+
if (options?.limit) {
|
|
98
|
+
query = query.limit(options.limit);
|
|
99
|
+
}
|
|
100
|
+
if (options?.offset) {
|
|
101
|
+
query = query.range(options.offset, options.offset + (options?.limit ?? 10) - 1);
|
|
102
|
+
}
|
|
103
|
+
const { data, error } = await query;
|
|
104
|
+
if (error || !data) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
return data.map((row) => this.mapToDomain(row));
|
|
108
|
+
}
|
|
109
|
+
async insert(org, _context) {
|
|
110
|
+
const columns = {
|
|
111
|
+
[this.configHelper.getColumnName('id')]: org.id,
|
|
112
|
+
[this.configHelper.getColumnName('ownerUserId')]: org.ownerUserId,
|
|
113
|
+
[this.configHelper.getColumnName('createdAt')]: org.createdAt.toISOString(),
|
|
114
|
+
[this.configHelper.getColumnName('updatedAt')]: org.updatedAt.toISOString(),
|
|
115
|
+
[this.configHelper.getColumnName('deletedAt')]: org.deletedAt?.toISOString() ?? null
|
|
116
|
+
};
|
|
117
|
+
const customFields = this.configHelper.customFieldsToDb(org);
|
|
118
|
+
Object.assign(columns, customFields);
|
|
119
|
+
const { error } = await this.getTable().insert(columns);
|
|
120
|
+
if (error) {
|
|
121
|
+
throw new Error(`Failed to insert organization: ${error.message}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async update(org, _context) {
|
|
125
|
+
const columns = {
|
|
126
|
+
[this.configHelper.getColumnName('ownerUserId')]: org.ownerUserId,
|
|
127
|
+
[this.configHelper.getColumnName('updatedAt')]: org.updatedAt.toISOString(),
|
|
128
|
+
[this.configHelper.getColumnName('deletedAt')]: org.deletedAt?.toISOString() ?? null
|
|
129
|
+
};
|
|
130
|
+
const rawCustom = this.configHelper.customFieldsToDb(org);
|
|
131
|
+
const cleanCustom = Object.fromEntries(Object.entries(rawCustom || {}).filter(([, v]) => v !== undefined));
|
|
132
|
+
Object.assign(columns, cleanCustom);
|
|
133
|
+
const updateData = Object.fromEntries(Object.entries(columns).filter(([, v]) => v !== undefined));
|
|
134
|
+
const { error } = await this.getTable()
|
|
135
|
+
.update(updateData)
|
|
136
|
+
.eq(this.configHelper.getColumnName('id'), org.id);
|
|
137
|
+
if (error) {
|
|
138
|
+
throw new Error(`Failed to update organization: ${error.message}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async delete(id, _context) {
|
|
142
|
+
const { error } = await this.getTable()
|
|
143
|
+
.delete()
|
|
144
|
+
.eq(this.configHelper.getColumnName('id'), id);
|
|
145
|
+
if (error) {
|
|
146
|
+
throw new Error(`Failed to delete organization: ${error.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=SupabaseOrganizationRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SupabaseOrganizationRepository.js","sourceRoot":"","sources":["../../src/repositories/SupabaseOrganizationRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase User Repository
|
|
3
|
+
*
|
|
4
|
+
* Implements UserRepository using Supabase client.
|
|
5
|
+
* Works in both Node.js and Deno/Edge Functions environments.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolkitOptions, User, UserRepository } from '@multitenantkit/domain-contracts';
|
|
8
|
+
import type { OperationContext } from '@multitenantkit/domain-contracts/shared';
|
|
9
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
10
|
+
/**
|
|
11
|
+
* Supabase implementation of UserRepository
|
|
12
|
+
*
|
|
13
|
+
* Generic support for custom fields and column mapping:
|
|
14
|
+
* - TCustomFields: Additional fields beyond the base User
|
|
15
|
+
* - Column mapping: Map framework field names to custom database column names
|
|
16
|
+
*/
|
|
17
|
+
export declare class SupabaseUserRepository<TCustomFields = {}> implements UserRepository {
|
|
18
|
+
private readonly client;
|
|
19
|
+
private readonly configHelper;
|
|
20
|
+
private readonly schemaName?;
|
|
21
|
+
private readonly tableName;
|
|
22
|
+
constructor(client: SupabaseClient, toolkitOptions?: ToolkitOptions<TCustomFields, unknown, unknown>);
|
|
23
|
+
/**
|
|
24
|
+
* Get the Supabase query builder for the users table
|
|
25
|
+
*/
|
|
26
|
+
private getTable;
|
|
27
|
+
/**
|
|
28
|
+
* Build select columns string
|
|
29
|
+
*/
|
|
30
|
+
private getSelectColumns;
|
|
31
|
+
/**
|
|
32
|
+
* Map database row to domain entity
|
|
33
|
+
*/
|
|
34
|
+
private mapToDomain;
|
|
35
|
+
/**
|
|
36
|
+
* Find a user by their ID
|
|
37
|
+
*/
|
|
38
|
+
findById(id: string): Promise<(User & TCustomFields) | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Find a user by their username (case-insensitive)
|
|
41
|
+
*/
|
|
42
|
+
findByUsername(username: string): Promise<(User & TCustomFields) | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Find user by external ID (auth provider ID) - case-insensitive
|
|
45
|
+
*/
|
|
46
|
+
findByExternalId(externalId: string): Promise<(User & TCustomFields) | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Insert a new user
|
|
49
|
+
*/
|
|
50
|
+
insert(user: User & TCustomFields, _context?: OperationContext): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Update an existing user
|
|
53
|
+
*/
|
|
54
|
+
update(user: User & TCustomFields, _context?: OperationContext): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Delete a user by ID
|
|
57
|
+
*/
|
|
58
|
+
delete(id: string, _context?: OperationContext): Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=SupabaseUserRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SupabaseUserRepository.d.ts","sourceRoot":"","sources":["../../src/repositories/SupabaseUserRepository.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAE7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D;;;;;;GAMG;AAEH,qBAAa,sBAAsB,CAAC,aAAa,GAAG,EAAE,CAAE,YAAW,cAAc;IAMzE,OAAO,CAAC,QAAQ,CAAC,MAAM;IAL3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4C;IACzE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGd,MAAM,EAAE,cAAc,EACvC,cAAc,CAAC,EAAE,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC;IAqBpE;;OAEG;IACH,OAAO,CAAC,QAAQ;IAOhB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IAclE;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IAc9E;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IAclF;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpF;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BpF;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CASvE"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase User Repository
|
|
3
|
+
*
|
|
4
|
+
* Implements UserRepository using Supabase client.
|
|
5
|
+
* Works in both Node.js and Deno/Edge Functions environments.
|
|
6
|
+
*/
|
|
7
|
+
import { UserRepositoryConfigHelper } from '@multitenantkit/domain-contracts';
|
|
8
|
+
import { UserMapper } from '../mappers/UserMapper';
|
|
9
|
+
/**
|
|
10
|
+
* Supabase implementation of UserRepository
|
|
11
|
+
*
|
|
12
|
+
* Generic support for custom fields and column mapping:
|
|
13
|
+
* - TCustomFields: Additional fields beyond the base User
|
|
14
|
+
* - Column mapping: Map framework field names to custom database column names
|
|
15
|
+
*/
|
|
16
|
+
// biome-ignore lint/complexity/noBannedTypes: Empty object {} is the correct default for optional custom fields
|
|
17
|
+
export class SupabaseUserRepository {
|
|
18
|
+
client;
|
|
19
|
+
configHelper;
|
|
20
|
+
schemaName;
|
|
21
|
+
tableName;
|
|
22
|
+
constructor(client, toolkitOptions) {
|
|
23
|
+
this.client = client;
|
|
24
|
+
// Extract user custom fields config from toolkit options
|
|
25
|
+
const userConfig = toolkitOptions?.users?.customFields;
|
|
26
|
+
// Extract database configuration with defaults
|
|
27
|
+
this.schemaName = toolkitOptions?.users?.database?.schema;
|
|
28
|
+
this.tableName = toolkitOptions?.users?.database?.table || 'users';
|
|
29
|
+
// Extract naming strategies
|
|
30
|
+
const databaseNamingStrategy = toolkitOptions?.users?.database?.namingStrategy;
|
|
31
|
+
const globalNamingStrategy = toolkitOptions?.namingStrategy;
|
|
32
|
+
// Use helper to handle configuration logic
|
|
33
|
+
this.configHelper = new UserRepositoryConfigHelper(userConfig, databaseNamingStrategy, globalNamingStrategy);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the Supabase query builder for the users table
|
|
37
|
+
*/
|
|
38
|
+
getTable() {
|
|
39
|
+
if (this.schemaName) {
|
|
40
|
+
return this.client.schema(this.schemaName).from(this.tableName);
|
|
41
|
+
}
|
|
42
|
+
return this.client.from(this.tableName);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build select columns string
|
|
46
|
+
*/
|
|
47
|
+
getSelectColumns() {
|
|
48
|
+
const cols = [
|
|
49
|
+
`${this.configHelper.getColumnName('id')}`,
|
|
50
|
+
`${this.configHelper.getColumnName('externalId')}`,
|
|
51
|
+
`${this.configHelper.getColumnName('username')}`,
|
|
52
|
+
`${this.configHelper.getColumnName('createdAt')}`,
|
|
53
|
+
`${this.configHelper.getColumnName('updatedAt')}`,
|
|
54
|
+
`${this.configHelper.getColumnName('deletedAt')}`
|
|
55
|
+
];
|
|
56
|
+
// If custom fields exist, select all columns
|
|
57
|
+
if (this.configHelper.hasCustomFields) {
|
|
58
|
+
return '*';
|
|
59
|
+
}
|
|
60
|
+
return cols.join(', ');
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Map database row to domain entity
|
|
64
|
+
*/
|
|
65
|
+
mapToDomain(row) {
|
|
66
|
+
return UserMapper.toDomainWithCustom(row, this.configHelper.columnMap, this.configHelper.hasCustomFields
|
|
67
|
+
? (dbRow) => this.configHelper.customFieldsToDomain(dbRow)
|
|
68
|
+
: undefined);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Find a user by their ID
|
|
72
|
+
*/
|
|
73
|
+
async findById(id) {
|
|
74
|
+
const { data, error } = await this.getTable()
|
|
75
|
+
.select(this.getSelectColumns())
|
|
76
|
+
.eq(this.configHelper.getColumnName('id'), id)
|
|
77
|
+
.limit(1)
|
|
78
|
+
.single();
|
|
79
|
+
if (error || !data) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return this.mapToDomain(data);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find a user by their username (case-insensitive)
|
|
86
|
+
*/
|
|
87
|
+
async findByUsername(username) {
|
|
88
|
+
const { data, error } = await this.getTable()
|
|
89
|
+
.select(this.getSelectColumns())
|
|
90
|
+
.ilike(this.configHelper.getColumnName('username'), username)
|
|
91
|
+
.limit(1)
|
|
92
|
+
.single();
|
|
93
|
+
if (error || !data) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return this.mapToDomain(data);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Find user by external ID (auth provider ID) - case-insensitive
|
|
100
|
+
*/
|
|
101
|
+
async findByExternalId(externalId) {
|
|
102
|
+
const { data, error } = await this.getTable()
|
|
103
|
+
.select(this.getSelectColumns())
|
|
104
|
+
.ilike(this.configHelper.getColumnName('externalId'), externalId)
|
|
105
|
+
.limit(1)
|
|
106
|
+
.single();
|
|
107
|
+
if (error || !data) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
return this.mapToDomain(data);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Insert a new user
|
|
114
|
+
*/
|
|
115
|
+
async insert(user, _context) {
|
|
116
|
+
// Build columns object with mapped column names
|
|
117
|
+
const columns = {
|
|
118
|
+
[this.configHelper.getColumnName('id')]: user.id,
|
|
119
|
+
[this.configHelper.getColumnName('externalId')]: user.externalId,
|
|
120
|
+
[this.configHelper.getColumnName('username')]: user.username,
|
|
121
|
+
[this.configHelper.getColumnName('createdAt')]: user.createdAt.toISOString(),
|
|
122
|
+
[this.configHelper.getColumnName('updatedAt')]: user.updatedAt.toISOString(),
|
|
123
|
+
[this.configHelper.getColumnName('deletedAt')]: user.deletedAt?.toISOString() ?? null
|
|
124
|
+
};
|
|
125
|
+
// Add custom fields using helper
|
|
126
|
+
const customFields = this.configHelper.customFieldsToDb(user);
|
|
127
|
+
Object.assign(columns, customFields);
|
|
128
|
+
const { error } = await this.getTable().insert(columns);
|
|
129
|
+
if (error) {
|
|
130
|
+
throw new Error(`Failed to insert user: ${error.message}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Update an existing user
|
|
135
|
+
*/
|
|
136
|
+
async update(user, _context) {
|
|
137
|
+
const columns = {
|
|
138
|
+
[this.configHelper.getColumnName('externalId')]: user.externalId,
|
|
139
|
+
[this.configHelper.getColumnName('username')]: user.username,
|
|
140
|
+
[this.configHelper.getColumnName('updatedAt')]: user.updatedAt.toISOString(),
|
|
141
|
+
[this.configHelper.getColumnName('deletedAt')]: user.deletedAt?.toISOString() ?? null
|
|
142
|
+
};
|
|
143
|
+
// Add custom fields using helper
|
|
144
|
+
const rawCustom = this.configHelper.customFieldsToDb(user);
|
|
145
|
+
const cleanCustom = Object.fromEntries(Object.entries(rawCustom || {}).filter(([, v]) => v !== undefined));
|
|
146
|
+
Object.assign(columns, cleanCustom);
|
|
147
|
+
// Remove undefined values
|
|
148
|
+
const updateData = Object.fromEntries(Object.entries(columns).filter(([, v]) => v !== undefined));
|
|
149
|
+
const { error } = await this.getTable()
|
|
150
|
+
.update(updateData)
|
|
151
|
+
.eq(this.configHelper.getColumnName('id'), user.id);
|
|
152
|
+
if (error) {
|
|
153
|
+
throw new Error(`Failed to update user: ${error.message}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Delete a user by ID
|
|
158
|
+
*/
|
|
159
|
+
async delete(id, _context) {
|
|
160
|
+
const { error } = await this.getTable()
|
|
161
|
+
.delete()
|
|
162
|
+
.eq(this.configHelper.getColumnName('id'), id);
|
|
163
|
+
if (error) {
|
|
164
|
+
throw new Error(`Failed to delete user: ${error.message}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=SupabaseUserRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SupabaseUserRepository.js","sourceRoot":"","sources":["../../src/repositories/SupabaseUserRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Clock
|
|
3
|
+
*
|
|
4
|
+
* Simple clock implementation using standard Date API.
|
|
5
|
+
* Deno/Edge Functions compatible - no Node.js dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import type { ClockPort } from '@multitenantkit/domain-contracts';
|
|
8
|
+
/**
|
|
9
|
+
* Clock implementation using standard Date API
|
|
10
|
+
*/
|
|
11
|
+
export declare class WebClock implements ClockPort {
|
|
12
|
+
/**
|
|
13
|
+
* Get the current date/time
|
|
14
|
+
*/
|
|
15
|
+
now(): Date;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=WebClock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebClock.d.ts","sourceRoot":"","sources":["../../src/system/WebClock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAElE;;GAEG;AACH,qBAAa,QAAS,YAAW,SAAS;IACtC;;OAEG;IACH,GAAG,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Clock
|
|
3
|
+
*
|
|
4
|
+
* Simple clock implementation using standard Date API.
|
|
5
|
+
* Deno/Edge Functions compatible - no Node.js dependencies.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Clock implementation using standard Date API
|
|
9
|
+
*/
|
|
10
|
+
export class WebClock {
|
|
11
|
+
/**
|
|
12
|
+
* Get the current date/time
|
|
13
|
+
*/
|
|
14
|
+
now() {
|
|
15
|
+
return new Date();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=WebClock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebClock.js","sourceRoot":"","sources":["../../src/system/WebClock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,OAAO,QAAQ;IACjB;;OAEG;IACH,GAAG;QACC,OAAO,IAAI,IAAI,EAAE,CAAC;IACtB,CAAC;CACJ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Crypto UUID Generator
|
|
3
|
+
*
|
|
4
|
+
* Uses the Web Crypto API (crypto.randomUUID()) which is available in:
|
|
5
|
+
* - Deno
|
|
6
|
+
* - Modern browsers
|
|
7
|
+
* - Node.js 19+
|
|
8
|
+
*
|
|
9
|
+
* This is Deno/Edge Functions compatible - no Node.js dependencies.
|
|
10
|
+
*/
|
|
11
|
+
import type { UuidPort } from '@multitenantkit/domain-contracts';
|
|
12
|
+
/**
|
|
13
|
+
* UUID generator using Web Crypto API
|
|
14
|
+
*/
|
|
15
|
+
export declare class WebCryptoUuid implements UuidPort {
|
|
16
|
+
/**
|
|
17
|
+
* Generate a new UUID v4
|
|
18
|
+
*/
|
|
19
|
+
generate(): string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=WebCryptoUuid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebCryptoUuid.d.ts","sourceRoot":"","sources":["../../src/system/WebCryptoUuid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAEjE;;GAEG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAC1C;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGrB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Crypto UUID Generator
|
|
3
|
+
*
|
|
4
|
+
* Uses the Web Crypto API (crypto.randomUUID()) which is available in:
|
|
5
|
+
* - Deno
|
|
6
|
+
* - Modern browsers
|
|
7
|
+
* - Node.js 19+
|
|
8
|
+
*
|
|
9
|
+
* This is Deno/Edge Functions compatible - no Node.js dependencies.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* UUID generator using Web Crypto API
|
|
13
|
+
*/
|
|
14
|
+
export class WebCryptoUuid {
|
|
15
|
+
/**
|
|
16
|
+
* Generate a new UUID v4
|
|
17
|
+
*/
|
|
18
|
+
generate() {
|
|
19
|
+
return crypto.randomUUID();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=WebCryptoUuid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebCryptoUuid.js","sourceRoot":"","sources":["../../src/system/WebCryptoUuid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;GAEG;AACH,MAAM,OAAO,aAAa;IACtB;;OAEG;IACH,QAAQ;QACJ,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/system/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/system/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@multitenantkit/adapter-persistence-supabase",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Supabase persistence adapter for MultiTenantKit - works in Node.js and Deno/Edge Functions",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"multitenantkit",
|
|
8
|
+
"saas",
|
|
9
|
+
"multi-tenant",
|
|
10
|
+
"multitenancy",
|
|
11
|
+
"adapter",
|
|
12
|
+
"persistence",
|
|
13
|
+
"supabase",
|
|
14
|
+
"database",
|
|
15
|
+
"edge-functions",
|
|
16
|
+
"deno",
|
|
17
|
+
"organizations",
|
|
18
|
+
"teams",
|
|
19
|
+
"users",
|
|
20
|
+
"typescript"
|
|
21
|
+
],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/multitenantkit/multitenantkit.git",
|
|
27
|
+
"directory": "packages/adapters/persistence/supabase"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/multitenantkit/multitenantkit/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/multitenantkit/multitenantkit#readme",
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"main": "./dist/index.js",
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"import": "./dist/index.js"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc --build",
|
|
50
|
+
"dev": "tsc --build --watch",
|
|
51
|
+
"clean": "rm -rf dist",
|
|
52
|
+
"type-check": "tsc --noEmit",
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"test:watch": "vitest",
|
|
55
|
+
"test:coverage": "vitest run --coverage"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@multitenantkit/domain": "^0.2.1",
|
|
59
|
+
"@multitenantkit/domain-contracts": "^0.2.0",
|
|
60
|
+
"@supabase/supabase-js": "^2.39.0",
|
|
61
|
+
"zod": "^3.22.4"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^20.0.0",
|
|
65
|
+
"typescript": "^5.0.0",
|
|
66
|
+
"vitest": "^1.0.0"
|
|
67
|
+
}
|
|
68
|
+
}
|