@fabriktor/fx 0.0.46 → 0.0.48
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/dist/src/auth/auth.d.ts +2 -0
- package/dist/src/chat/chat.d.ts +2 -13
- package/dist/src/chat/chat.js +0 -31
- package/dist/src/fx.js +0 -1
- package/dist/src/session/session.d.ts +3 -0
- package/dist/src/session/session.js +5 -0
- package/dist/src/users/users.d.ts +16 -1
- package/dist/src/users/users.js +101 -0
- package/package.json +1 -1
package/dist/src/auth/auth.d.ts
CHANGED
|
@@ -2,12 +2,14 @@ export type AuthEmailOptions = {
|
|
|
2
2
|
email: string;
|
|
3
3
|
password: string;
|
|
4
4
|
};
|
|
5
|
+
export type UpdateAuthEmailOptions = Pick<AuthEmailOptions, "email">;
|
|
5
6
|
export type AuthSession = {
|
|
6
7
|
token: string;
|
|
7
8
|
};
|
|
8
9
|
export interface AuthOperator {
|
|
9
10
|
signUp(opts: AuthEmailOptions): Promise<AuthSession>;
|
|
10
11
|
signIn(opts: AuthEmailOptions): Promise<AuthSession>;
|
|
12
|
+
updateEmail(opts: UpdateAuthEmailOptions): Promise<void>;
|
|
11
13
|
getToken(): Promise<string>;
|
|
12
14
|
refreshToken(): Promise<string>;
|
|
13
15
|
emailVerified(): boolean;
|
package/dist/src/chat/chat.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ChatOperator,
|
|
2
|
-
import type { Chat, ChatRoom, ChatRoomMember
|
|
1
|
+
import type { ChatOperator, WSCloseHandler, WSConnection, WSErrorHandler, WSMessageHandler } from "@fabriktor/client";
|
|
2
|
+
import type { Chat, ChatRoom, ChatRoomMember } from "@fabriktor/schema";
|
|
3
3
|
import { type SearchPage } from "../core/search.js";
|
|
4
4
|
type ChatInsertOptions = Parameters<ChatOperator["insertOneChat"]>[0];
|
|
5
5
|
type ChatReplaceOptions = Parameters<ChatOperator["replaceOneChat"]>[0];
|
|
@@ -10,7 +10,6 @@ export type MarkChatObjectsUploadedOptions = {
|
|
|
10
10
|
export type ReactChatOptions = Parameters<ChatOperator["reactChat"]>[0];
|
|
11
11
|
export type ChatFXOptions = {
|
|
12
12
|
chat: ChatOperator;
|
|
13
|
-
users: UsersOperator;
|
|
14
13
|
};
|
|
15
14
|
type SearchChatsScope = {
|
|
16
15
|
chat_room_id: string;
|
|
@@ -61,13 +60,6 @@ export type ChatRoomMembersOptions = {
|
|
|
61
60
|
export type MyChatRoomMembersOptions = {
|
|
62
61
|
owner_id: string;
|
|
63
62
|
};
|
|
64
|
-
export type ChatRoomParticipantsOptions = {
|
|
65
|
-
chat_room_ids: string[];
|
|
66
|
-
};
|
|
67
|
-
export type ChatRoomParticipants = {
|
|
68
|
-
members: ChatRoomMember[];
|
|
69
|
-
users: User[];
|
|
70
|
-
};
|
|
71
63
|
export type OpenChatRoomOptions = {
|
|
72
64
|
owner_id: string;
|
|
73
65
|
chat_room_id: string;
|
|
@@ -110,14 +102,12 @@ export interface ChatFXOperator {
|
|
|
110
102
|
searchChatRoomMembers(opts: SearchChatRoomMembersOptions): Promise<SearchChatRoomMembersPage>;
|
|
111
103
|
chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
|
|
112
104
|
myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
|
|
113
|
-
chatRoomParticipants(opts: ChatRoomParticipantsOptions): Promise<ChatRoomParticipants>;
|
|
114
105
|
openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
|
|
115
106
|
openGlobalChatRooms(opts: OpenGlobalChatRoomsOptions): Promise<GlobalChatRoomsSession>;
|
|
116
107
|
reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
|
|
117
108
|
}
|
|
118
109
|
export declare class ChatFX implements ChatFXOperator {
|
|
119
110
|
private chat;
|
|
120
|
-
private users;
|
|
121
111
|
constructor(opts: ChatFXOptions);
|
|
122
112
|
createChat(opts: CreateChatOptions): Promise<Chat>;
|
|
123
113
|
markChatObjectsUploaded(opts: MarkChatObjectsUploadedOptions): Promise<Chat>;
|
|
@@ -128,7 +118,6 @@ export declare class ChatFX implements ChatFXOperator {
|
|
|
128
118
|
searchChatRoomMembers(opts: SearchChatRoomMembersOptions): Promise<SearchChatRoomMembersPage>;
|
|
129
119
|
chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
|
|
130
120
|
myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
|
|
131
|
-
chatRoomParticipants(opts: ChatRoomParticipantsOptions): Promise<ChatRoomParticipants>;
|
|
132
121
|
openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
|
|
133
122
|
openGlobalChatRooms(opts: OpenGlobalChatRoomsOptions): Promise<GlobalChatRoomsSession>;
|
|
134
123
|
reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
|
package/dist/src/chat/chat.js
CHANGED
|
@@ -16,10 +16,8 @@ const msgSearchQueryRequired = "Search query is required.";
|
|
|
16
16
|
const msgChatObjectsUploading = "Cannot react to a chat while objects are still uploading.";
|
|
17
17
|
export class ChatFX {
|
|
18
18
|
chat;
|
|
19
|
-
users;
|
|
20
19
|
constructor(opts) {
|
|
21
20
|
this.chat = opts.chat;
|
|
22
|
-
this.users = opts.users;
|
|
23
21
|
}
|
|
24
22
|
async createChat(opts) {
|
|
25
23
|
const out = await this.chat.insertOneChat(opts);
|
|
@@ -113,29 +111,6 @@ export class ChatFX {
|
|
|
113
111
|
});
|
|
114
112
|
return out.value ?? [];
|
|
115
113
|
}
|
|
116
|
-
async chatRoomParticipants(opts) {
|
|
117
|
-
const chat_room_ids = normalizeIDs(opts.chat_room_ids);
|
|
118
|
-
if (chat_room_ids.length === 0) {
|
|
119
|
-
return { members: [], users: [] };
|
|
120
|
-
}
|
|
121
|
-
const memberGroups = await Promise.all(chat_room_ids.map((chat_room_id) => this.chatRoomMembers({
|
|
122
|
-
chat_room_id,
|
|
123
|
-
})));
|
|
124
|
-
const members = uniqueChatRoomMembers(memberGroups.flat());
|
|
125
|
-
const owner_ids = normalizeIDs(members.map((member) => member.owner_id));
|
|
126
|
-
if (owner_ids.length === 0) {
|
|
127
|
-
return { members, users: [] };
|
|
128
|
-
}
|
|
129
|
-
const out = await this.users.queryUsers({
|
|
130
|
-
query: {
|
|
131
|
-
id: owner_ids,
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
|
-
return {
|
|
135
|
-
members,
|
|
136
|
-
users: out.value ?? [],
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
114
|
async openChatRoom(opts) {
|
|
140
115
|
const latest = await this.latestChats({
|
|
141
116
|
chat_room_id: opts.chat_room_id,
|
|
@@ -414,12 +389,6 @@ export class ChatFX {
|
|
|
414
389
|
export function newChatFX(opts) {
|
|
415
390
|
return new ChatFX(opts);
|
|
416
391
|
}
|
|
417
|
-
function normalizeIDs(ids) {
|
|
418
|
-
return [...new Set(ids.map((id) => id.trim()).filter((id) => id !== ""))];
|
|
419
|
-
}
|
|
420
|
-
function uniqueChatRoomMembers(members) {
|
|
421
|
-
return [...new Map(members.map((member) => [member.id, member])).values()];
|
|
422
|
-
}
|
|
423
392
|
function latestChatsPage(opts) {
|
|
424
393
|
return {
|
|
425
394
|
chats: opts.raw.results,
|
package/dist/src/fx.js
CHANGED
|
@@ -4,6 +4,7 @@ import type { UsersFXOperator } from "../users/users.js";
|
|
|
4
4
|
type ConnectionInsert = Parameters<ConnectionsOperator["insertOneConnection"]>[0]["in"];
|
|
5
5
|
type BootstrapInput = Parameters<UsersOperator["bootstrap"]>[0]["in"];
|
|
6
6
|
type BootstrapResult = Awaited<ReturnType<UsersOperator["bootstrap"]>>;
|
|
7
|
+
type UpdateEmailOptions = Parameters<AuthOperator["updateEmail"]>[0];
|
|
7
8
|
export declare const SignInMode: {
|
|
8
9
|
readonly Email: "email";
|
|
9
10
|
readonly Username: "username";
|
|
@@ -31,6 +32,7 @@ export interface SessionFXOperator {
|
|
|
31
32
|
signUpAndBootstrap(opts: SignUpAndBootstrapOptions): Promise<BootstrapResult>;
|
|
32
33
|
signIn(opts: SignInOptions): Promise<void>;
|
|
33
34
|
signInWithEmail(opts: SignInWithEmailOptions): Promise<void>;
|
|
35
|
+
updateEmail(opts: UpdateEmailOptions): Promise<void>;
|
|
34
36
|
checkEmailVerification(): Promise<boolean>;
|
|
35
37
|
}
|
|
36
38
|
export declare class SessionFX implements SessionFXOperator {
|
|
@@ -42,6 +44,7 @@ export declare class SessionFX implements SessionFXOperator {
|
|
|
42
44
|
signUpAndBootstrap(opts: SignUpAndBootstrapOptions): Promise<BootstrapResult>;
|
|
43
45
|
signIn(opts: SignInOptions): Promise<void>;
|
|
44
46
|
signInWithEmail(opts: SignInWithEmailOptions): Promise<void>;
|
|
47
|
+
updateEmail(opts: UpdateEmailOptions): Promise<void>;
|
|
45
48
|
checkEmailVerification(): Promise<boolean>;
|
|
46
49
|
}
|
|
47
50
|
export declare function newSessionFX(opts: SessionFXOptions): SessionFX;
|
|
@@ -49,6 +49,11 @@ export class SessionFX {
|
|
|
49
49
|
});
|
|
50
50
|
await this.users.sync();
|
|
51
51
|
}
|
|
52
|
+
async updateEmail(opts) {
|
|
53
|
+
await this.auth.updateEmail(opts);
|
|
54
|
+
await this.auth.refreshToken();
|
|
55
|
+
await this.users.sync();
|
|
56
|
+
}
|
|
52
57
|
async checkEmailVerification() {
|
|
53
58
|
await this.auth.reloadUser();
|
|
54
59
|
if (!this.auth.emailVerified()) {
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import type { GetByUIDOptions, OperationResultOf, TmpPhonesOperator, TmpUsernamesOperator, UsernameVerification, UsersOperator } from "@fabriktor/client";
|
|
2
|
-
import type { User } from "@fabriktor/schema";
|
|
2
|
+
import type { InAddress, InUser, User } from "@fabriktor/schema";
|
|
3
3
|
import { type RunSearchOptions, type SearchPage } from "../core/search.js";
|
|
4
4
|
export type ResolveUsernameOptions = Parameters<UsersOperator["resolveUsername"]>[0];
|
|
5
5
|
export type VerifyUsernameOptions = Parameters<TmpUsernamesOperator["verify"]>[0];
|
|
6
6
|
export type GenerateUsernamesOptions = VerifyUsernameOptions;
|
|
7
7
|
export type SearchUsersOptions = GetByUIDOptions & Omit<RunSearchOptions<User>, "search">;
|
|
8
8
|
export type SearchUsersPage = SearchPage<User>;
|
|
9
|
+
export type UserProfileInput = Pick<InUser, "first_name" | "last_name" | "phone" | "company_name" | "privacy"> & InAddress;
|
|
10
|
+
export type UpdateUserProfileOptions = GetByUIDOptions & {
|
|
11
|
+
id: string;
|
|
12
|
+
in: UserProfileInput;
|
|
13
|
+
};
|
|
14
|
+
export type UpdateUserPhoneOptions = GetByUIDOptions & {
|
|
15
|
+
id: string;
|
|
16
|
+
phone: string;
|
|
17
|
+
code: string;
|
|
18
|
+
};
|
|
9
19
|
export type SendPhoneCodeOptions = Parameters<TmpPhonesOperator["send"]>[0];
|
|
10
20
|
export type VerifyPhoneCodeOptions = Parameters<TmpPhonesOperator["verify"]>[0];
|
|
11
21
|
export type UsersFXOptions = {
|
|
@@ -15,6 +25,8 @@ export type UsersFXOptions = {
|
|
|
15
25
|
};
|
|
16
26
|
export interface UsersFXOperator {
|
|
17
27
|
searchUsers(opts: SearchUsersOptions): Promise<SearchUsersPage>;
|
|
28
|
+
updateUserProfile(opts: UpdateUserProfileOptions): Promise<User>;
|
|
29
|
+
updateUserPhone(opts: UpdateUserPhoneOptions): Promise<User>;
|
|
18
30
|
resolveUsername(opts: ResolveUsernameOptions): Promise<string>;
|
|
19
31
|
verifyUsername(opts: VerifyUsernameOptions): Promise<OperationResultOf<UsernameVerification>>;
|
|
20
32
|
generateUsernames(opts: GenerateUsernamesOptions): Promise<OperationResultOf<UsernameVerification>>;
|
|
@@ -27,10 +39,13 @@ export declare class UsersFX implements UsersFXOperator {
|
|
|
27
39
|
private tmp_phones;
|
|
28
40
|
constructor(opts: UsersFXOptions);
|
|
29
41
|
searchUsers(opts: SearchUsersOptions): Promise<SearchUsersPage>;
|
|
42
|
+
updateUserProfile(opts: UpdateUserProfileOptions): Promise<User>;
|
|
43
|
+
updateUserPhone(opts: UpdateUserPhoneOptions): Promise<User>;
|
|
30
44
|
resolveUsername(opts: ResolveUsernameOptions): Promise<string>;
|
|
31
45
|
verifyUsername(opts: VerifyUsernameOptions): Promise<OperationResultOf<UsernameVerification>>;
|
|
32
46
|
generateUsernames(opts: GenerateUsernamesOptions): Promise<OperationResultOf<UsernameVerification>>;
|
|
33
47
|
sendPhoneCode(opts: SendPhoneCodeOptions): Promise<void>;
|
|
34
48
|
verifyPhoneCode(opts: VerifyPhoneCodeOptions): Promise<void>;
|
|
49
|
+
private updatedUser;
|
|
35
50
|
}
|
|
36
51
|
export declare function newUsersFX(opts: UsersFXOptions): UsersFX;
|
package/dist/src/users/users.js
CHANGED
|
@@ -10,7 +10,12 @@ import { normalizeUsername, validateUsernameFormat } from "./username.js";
|
|
|
10
10
|
const msgUnableToResolveUsername = "Unable to resolve username.";
|
|
11
11
|
const msgPhoneRequired = "Phone number is required.";
|
|
12
12
|
const msgPhoneCodeRequired = "Verification code is required.";
|
|
13
|
+
const msgFirstNameRequired = "First name is required.";
|
|
14
|
+
const msgLastNameRequired = "Last name is required.";
|
|
15
|
+
const msgAddressRequired = "A complete address is required.";
|
|
16
|
+
const msgUserMissingAfterUpdate = "User could not be resolved after the profile update.";
|
|
13
17
|
const resourceUsername = "username";
|
|
18
|
+
const resourceUser = "user";
|
|
14
19
|
export class UsersFX {
|
|
15
20
|
users;
|
|
16
21
|
tmp_usernames;
|
|
@@ -30,6 +35,31 @@ export class UsersFX {
|
|
|
30
35
|
}),
|
|
31
36
|
});
|
|
32
37
|
}
|
|
38
|
+
async updateUserProfile(opts) {
|
|
39
|
+
const input = normalizeUserProfileInput(opts.in);
|
|
40
|
+
validateUserProfileInput(input);
|
|
41
|
+
await this.users.replaceOneUser({
|
|
42
|
+
id: opts.id,
|
|
43
|
+
in: input,
|
|
44
|
+
});
|
|
45
|
+
return await this.updatedUser(opts.uid);
|
|
46
|
+
}
|
|
47
|
+
async updateUserPhone(opts) {
|
|
48
|
+
const phone = normalizePhone(opts.phone);
|
|
49
|
+
const code = normalizePhoneCode(opts.code);
|
|
50
|
+
if (!validatePhone(phone)) {
|
|
51
|
+
throw errPhoneRequired("phone");
|
|
52
|
+
}
|
|
53
|
+
if (!validatePhoneCode(code)) {
|
|
54
|
+
throw errPhoneCodeRequired("code");
|
|
55
|
+
}
|
|
56
|
+
await this.tmp_phones.verify({ phone, code });
|
|
57
|
+
await this.users.replaceOneUser({
|
|
58
|
+
id: opts.id,
|
|
59
|
+
in: { phone },
|
|
60
|
+
});
|
|
61
|
+
return await this.updatedUser(opts.uid);
|
|
62
|
+
}
|
|
33
63
|
async resolveUsername(opts) {
|
|
34
64
|
const username = normalizeUsername(opts.username);
|
|
35
65
|
const out = await this.users.resolveUsername({
|
|
@@ -81,10 +111,81 @@ export class UsersFX {
|
|
|
81
111
|
code,
|
|
82
112
|
});
|
|
83
113
|
}
|
|
114
|
+
async updatedUser(uid) {
|
|
115
|
+
const out = await this.users.getByUID({ uid });
|
|
116
|
+
const user = out.value?.[0];
|
|
117
|
+
if (!user) {
|
|
118
|
+
throw errResolveFailed({
|
|
119
|
+
resource: resourceUser,
|
|
120
|
+
msg: msgUserMissingAfterUpdate,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return user;
|
|
124
|
+
}
|
|
84
125
|
}
|
|
85
126
|
export function newUsersFX(opts) {
|
|
86
127
|
return new UsersFX(opts);
|
|
87
128
|
}
|
|
129
|
+
function normalizeUserProfileInput(input) {
|
|
130
|
+
return {
|
|
131
|
+
first_name: input.first_name.trim(),
|
|
132
|
+
last_name: input.last_name.trim(),
|
|
133
|
+
phone: input.phone.trim(),
|
|
134
|
+
company_name: input.company_name.trim(),
|
|
135
|
+
privacy: {
|
|
136
|
+
is_searchable: input.privacy.is_searchable,
|
|
137
|
+
is_messageable: input.privacy.is_messageable,
|
|
138
|
+
},
|
|
139
|
+
lat: input.lat,
|
|
140
|
+
lon: input.lon,
|
|
141
|
+
street: input.street.trim(),
|
|
142
|
+
city: input.city.trim(),
|
|
143
|
+
state: input.state.trim(),
|
|
144
|
+
postal_code: input.postal_code.trim(),
|
|
145
|
+
country: input.country.trim(),
|
|
146
|
+
formatted_address: input.formatted_address.trim(),
|
|
147
|
+
place_name: input.place_name.trim(),
|
|
148
|
+
place_id: input.place_id.trim(),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function validateUserProfileInput(input) {
|
|
152
|
+
if (!input.first_name) {
|
|
153
|
+
throw errRequired({
|
|
154
|
+
field: "first_name",
|
|
155
|
+
msg: msgFirstNameRequired,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (!input.last_name) {
|
|
159
|
+
throw errRequired({
|
|
160
|
+
field: "last_name",
|
|
161
|
+
msg: msgLastNameRequired,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (input.phone && !validatePhone(input.phone)) {
|
|
165
|
+
throw errValidation({
|
|
166
|
+
field: "phone",
|
|
167
|
+
msg: msgPhoneRequired,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (!hasCompleteAddress(input)) {
|
|
171
|
+
throw errValidation({
|
|
172
|
+
field: "formatted_address",
|
|
173
|
+
msg: msgAddressRequired,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function hasCompleteAddress(input) {
|
|
178
|
+
return (input.lat !== 0 &&
|
|
179
|
+
input.lon !== 0 &&
|
|
180
|
+
input.street.length > 0 &&
|
|
181
|
+
input.city.length > 0 &&
|
|
182
|
+
input.state.length > 0 &&
|
|
183
|
+
input.postal_code.length > 0 &&
|
|
184
|
+
input.country.length > 0 &&
|
|
185
|
+
input.formatted_address.length > 0 &&
|
|
186
|
+
input.place_name.length > 0 &&
|
|
187
|
+
input.place_id.length > 0);
|
|
188
|
+
}
|
|
88
189
|
function errUsernameResolveFailed(field) {
|
|
89
190
|
return errResolveFailed({
|
|
90
191
|
resource: resourceUsername,
|