@fabriktor/fx 0.0.30 → 0.0.32

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.
@@ -0,0 +1,50 @@
1
+ import type { InBill, OperationResult, PLBillablePeriodsFromDates, PLBillableSetItemQuantity, PLBillableVendorInvoiceFromBill, PLBillableYearSpan, RPBillablePeriodsFromDates, YearSpan } from "@fabriktor/schema";
2
+ import type { BillableOperator, OperationResultOf } from "@fabriktor/client";
3
+ export type BillableFXOptions = {
4
+ billable: BillableOperator;
5
+ };
6
+ export type GenerateFixedEstimateOptions = {
7
+ in: InBill;
8
+ };
9
+ export type AcceptFixedEstimateOptions = {
10
+ in: InBill;
11
+ };
12
+ export type GenerateDynamicEstimateOptions = {
13
+ in: InBill;
14
+ };
15
+ export type GenerateDynamicBillOptions = {
16
+ in: InBill;
17
+ exclude_billed?: boolean;
18
+ };
19
+ export type MarkLocationAchievedOptions = {
20
+ in: InBill;
21
+ };
22
+ export type YearSpanOptions = PLBillableYearSpan;
23
+ export type PeriodsFromDatesOptions = PLBillablePeriodsFromDates;
24
+ export type VendorInvoiceFromBillOptions = PLBillableVendorInvoiceFromBill;
25
+ export type SetItemQuantityOptions = PLBillableSetItemQuantity;
26
+ export interface BillableFXOperator {
27
+ generateFixedEstimate(opts: GenerateFixedEstimateOptions): Promise<OperationResult>;
28
+ acceptFixedEstimate(opts: AcceptFixedEstimateOptions): Promise<OperationResult>;
29
+ generateDynamicEstimate(opts: GenerateDynamicEstimateOptions): Promise<OperationResult>;
30
+ generateDynamicBill(opts: GenerateDynamicBillOptions): Promise<OperationResult>;
31
+ markLocationAchieved(opts: MarkLocationAchievedOptions): Promise<OperationResult>;
32
+ yearSpan(opts: YearSpanOptions): Promise<OperationResultOf<YearSpan>>;
33
+ periodsFromDates(opts: PeriodsFromDatesOptions): Promise<OperationResultOf<RPBillablePeriodsFromDates>>;
34
+ vendorInvoiceFromBill(opts: VendorInvoiceFromBillOptions): Promise<OperationResult>;
35
+ setItemQuantity(opts: SetItemQuantityOptions): Promise<void>;
36
+ }
37
+ export declare class BillableFX implements BillableFXOperator {
38
+ private billable;
39
+ constructor(opts: BillableFXOptions);
40
+ generateFixedEstimate(opts: GenerateFixedEstimateOptions): Promise<OperationResult>;
41
+ acceptFixedEstimate(opts: AcceptFixedEstimateOptions): Promise<OperationResult>;
42
+ generateDynamicEstimate(opts: GenerateDynamicEstimateOptions): Promise<OperationResult>;
43
+ generateDynamicBill(opts: GenerateDynamicBillOptions): Promise<OperationResult>;
44
+ markLocationAchieved(opts: MarkLocationAchievedOptions): Promise<OperationResult>;
45
+ yearSpan(opts: YearSpanOptions): Promise<OperationResultOf<YearSpan>>;
46
+ periodsFromDates(opts: PeriodsFromDatesOptions): Promise<OperationResultOf<RPBillablePeriodsFromDates>>;
47
+ vendorInvoiceFromBill(opts: VendorInvoiceFromBillOptions): Promise<OperationResult>;
48
+ setItemQuantity(opts: SetItemQuantityOptions): Promise<void>;
49
+ }
50
+ export declare function newBillableFX(opts: BillableFXOptions): BillableFX;
@@ -0,0 +1,74 @@
1
+ // Copyright (C) Fabriktor, Inc. 2025-present.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ // not use this file except in compliance with the License. You may obtain
5
+ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ const billTypeFixed = "fixed";
7
+ const billTypeDynamic = "dynamic";
8
+ export class BillableFX {
9
+ billable;
10
+ constructor(opts) {
11
+ this.billable = opts.billable;
12
+ }
13
+ async generateFixedEstimate(opts) {
14
+ return await this.billable.generateBill(billWith(opts.in, {
15
+ type: billTypeFixed,
16
+ is_estimate: true,
17
+ }));
18
+ }
19
+ async acceptFixedEstimate(opts) {
20
+ return await this.billable.generateBill(billWith(opts.in, {
21
+ type: billTypeFixed,
22
+ is_estimate: false,
23
+ }));
24
+ }
25
+ async generateDynamicEstimate(opts) {
26
+ return await this.billable.generateBill(billWith(opts.in, {
27
+ type: billTypeDynamic,
28
+ is_estimate: true,
29
+ }));
30
+ }
31
+ async generateDynamicBill(opts) {
32
+ return await this.billable.generateBill(billWith(opts.in, {
33
+ type: billTypeDynamic,
34
+ is_estimate: false,
35
+ exclude_billed: opts.exclude_billed,
36
+ }));
37
+ }
38
+ async markLocationAchieved(opts) {
39
+ return await this.billable.generateBill(billWith(opts.in, {
40
+ is_location_achieved: true,
41
+ }));
42
+ }
43
+ async yearSpan(opts) {
44
+ return await this.billable.yearSpan(opts);
45
+ }
46
+ async periodsFromDates(opts) {
47
+ return await this.billable.periodsFromDates(opts);
48
+ }
49
+ async vendorInvoiceFromBill(opts) {
50
+ return await this.billable.vendorInvoiceFromBill(opts);
51
+ }
52
+ async setItemQuantity(opts) {
53
+ await this.billable.setItemQuantity(opts);
54
+ }
55
+ }
56
+ export function newBillableFX(opts) {
57
+ return new BillableFX(opts);
58
+ }
59
+ function billWith(x, overrides) {
60
+ const out = {
61
+ ...x,
62
+ ...defined(overrides),
63
+ };
64
+ return out;
65
+ }
66
+ function defined(x) {
67
+ const out = {};
68
+ for (const [k, v] of Object.entries(x)) {
69
+ if (v !== undefined) {
70
+ out[k] = v;
71
+ }
72
+ }
73
+ return out;
74
+ }
@@ -0,0 +1,33 @@
1
+ import type { PLCallsMintVideoToken, PLNotificationsRelay } from "@fabriktor/schema";
2
+ import type { CallsOperator, NotificationsOperator } from "@fabriktor/client";
3
+ export type MintVideoTokenOptions = PLCallsMintVideoToken;
4
+ export type StartCallOptions = {
5
+ mint: MintVideoTokenOptions;
6
+ notification: PLNotificationsRelay;
7
+ };
8
+ export type AnswerCallOptions = {
9
+ mint: MintVideoTokenOptions;
10
+ self_notification: PLNotificationsRelay;
11
+ };
12
+ export type CancelCallOptions = {
13
+ notification: PLNotificationsRelay;
14
+ };
15
+ export type CallsFXOptions = {
16
+ calls: CallsOperator;
17
+ notifications: NotificationsOperator;
18
+ };
19
+ export interface CallsFXOperator {
20
+ startCall(opts: StartCallOptions): Promise<string>;
21
+ answerCall(opts: AnswerCallOptions): Promise<string>;
22
+ cancelCall(opts: CancelCallOptions): Promise<void>;
23
+ }
24
+ export declare class CallsFX implements CallsFXOperator {
25
+ private calls;
26
+ private notifications;
27
+ constructor(opts: CallsFXOptions);
28
+ startCall(opts: StartCallOptions): Promise<string>;
29
+ answerCall(opts: AnswerCallOptions): Promise<string>;
30
+ cancelCall(opts: CancelCallOptions): Promise<void>;
31
+ private requireVideoToken;
32
+ }
33
+ export declare function newCallsFX(opts: CallsFXOptions): CallsFX;
@@ -0,0 +1,43 @@
1
+ // Copyright (C) Fabriktor, Inc. 2025-present.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ // not use this file except in compliance with the License. You may obtain
5
+ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ import { errResolveFailed } from "../core/err.js";
7
+ const resourceVideoToken = "video_token";
8
+ const msgUnableToMintVideoToken = "Unable to mint video token.";
9
+ export class CallsFX {
10
+ calls;
11
+ notifications;
12
+ constructor(opts) {
13
+ this.calls = opts.calls;
14
+ this.notifications = opts.notifications;
15
+ }
16
+ async startCall(opts) {
17
+ const token = await this.requireVideoToken(opts.mint);
18
+ await this.notifications.relayNotification(opts.notification);
19
+ return token;
20
+ }
21
+ async answerCall(opts) {
22
+ const token = await this.requireVideoToken(opts.mint);
23
+ await this.notifications.relayNotification(opts.self_notification);
24
+ return token;
25
+ }
26
+ async cancelCall(opts) {
27
+ await this.notifications.relayNotification(opts.notification);
28
+ }
29
+ async requireVideoToken(opts) {
30
+ const out = await this.calls.mintVideoToken(opts);
31
+ const token = out.value?.trim();
32
+ if (token === undefined || token === "") {
33
+ throw errResolveFailed({
34
+ resource: resourceVideoToken,
35
+ msg: msgUnableToMintVideoToken,
36
+ });
37
+ }
38
+ return token;
39
+ }
40
+ }
41
+ export function newCallsFX(opts) {
42
+ return new CallsFX(opts);
43
+ }
@@ -0,0 +1,89 @@
1
+ import { type Chat, type ChatRoom, type ChatRoomMember, type PLChatReact } from "@fabriktor/schema";
2
+ import type { ChatOperator, WSCloseHandler, WSConnection, WSErrorHandler, WSMessageHandler } from "@fabriktor/client";
3
+ export type ChatFXOptions = {
4
+ chat: ChatOperator;
5
+ };
6
+ export type LatestChatsOptions = {
7
+ chat_room_id: string;
8
+ page?: number;
9
+ per_page?: number;
10
+ };
11
+ export type LatestChatsCursor = {
12
+ chat_room_id: string;
13
+ next_page: number;
14
+ per_page: number;
15
+ done: boolean;
16
+ };
17
+ export type NextLatestChatsOptions = {
18
+ cursor: LatestChatsCursor;
19
+ };
20
+ export type LatestChatsPage = {
21
+ chats: Chat[];
22
+ page: number;
23
+ per_page: number;
24
+ total_count?: number;
25
+ last_page?: number;
26
+ has_more: boolean;
27
+ next_cursor: LatestChatsCursor;
28
+ };
29
+ export type ChatRoomMembersOptions = {
30
+ chat_room_id: string;
31
+ };
32
+ export type MyChatRoomMembersOptions = {
33
+ owner_id: string;
34
+ };
35
+ export type OpenChatRoomOptions = {
36
+ owner_id: string;
37
+ chat_room_id: string;
38
+ per_page?: number;
39
+ on_chat: WSMessageHandler<Chat>;
40
+ on_chat_room: WSMessageHandler<ChatRoom>;
41
+ on_error?: WSErrorHandler;
42
+ on_close?: WSCloseHandler;
43
+ };
44
+ export type OpenGlobalChatRoomsOptions = {
45
+ owner_id: string;
46
+ on_chat_room: WSMessageHandler<ChatRoom>;
47
+ on_error?: WSErrorHandler;
48
+ on_close?: WSCloseHandler;
49
+ };
50
+ export type ReactUploadedChatOptions = {
51
+ chat: Chat;
52
+ reaction: PLChatReact;
53
+ };
54
+ export type ChatRoomSession = {
55
+ latest: LatestChatsPage;
56
+ chats_ws: WSConnection;
57
+ chat_room_ws: WSConnection;
58
+ closeNormal(reason?: string): void;
59
+ closeLeavingPage(reason?: string): void;
60
+ };
61
+ export type GlobalChatRoomsSession = {
62
+ members: ChatRoomMember[];
63
+ chat_rooms_ws: WSConnection;
64
+ closeNormal(reason?: string): void;
65
+ closeLeavingPage(reason?: string): void;
66
+ };
67
+ export interface ChatFXOperator {
68
+ newLatestChatsCursor(opts: LatestChatsOptions): LatestChatsCursor;
69
+ latestChats(opts: LatestChatsOptions): Promise<LatestChatsPage>;
70
+ nextLatestChats(opts: NextLatestChatsOptions): Promise<LatestChatsPage>;
71
+ chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
72
+ myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
73
+ openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
74
+ openGlobalChatRooms(opts: OpenGlobalChatRoomsOptions): Promise<GlobalChatRoomsSession>;
75
+ reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
76
+ }
77
+ export declare class ChatFX implements ChatFXOperator {
78
+ private chat;
79
+ constructor(opts: ChatFXOptions);
80
+ newLatestChatsCursor(opts: LatestChatsOptions): LatestChatsCursor;
81
+ latestChats(opts: LatestChatsOptions): Promise<LatestChatsPage>;
82
+ nextLatestChats(opts: NextLatestChatsOptions): Promise<LatestChatsPage>;
83
+ chatRoomMembers(opts: ChatRoomMembersOptions): Promise<ChatRoomMember[]>;
84
+ myChatRoomMembers(opts: MyChatRoomMembersOptions): Promise<ChatRoomMember[]>;
85
+ openChatRoom(opts: OpenChatRoomOptions): Promise<ChatRoomSession>;
86
+ openGlobalChatRooms(opts: OpenGlobalChatRoomsOptions): Promise<GlobalChatRoomsSession>;
87
+ reactUploadedChat(opts: ReactUploadedChatOptions): Promise<void>;
88
+ }
89
+ export declare function newChatFX(opts: ChatFXOptions): ChatFX;
@@ -0,0 +1,194 @@
1
+ // Copyright (C) Fabriktor, Inc. 2025-present.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ // not use this file except in compliance with the License. You may obtain
5
+ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ import { SearchPageKey, SearchPerPageKey, SearchResultResultsKey, } from "@fabriktor/schema";
7
+ import { errValidation } from "../core/err.js";
8
+ const firstPage = 1;
9
+ const defaultPerPage = 30;
10
+ const closeCodeNormal = 1000;
11
+ const closeCodeLeavingPage = 1001;
12
+ const msgChatObjectsUploading = "Cannot react to a chat while objects are still uploading.";
13
+ export class ChatFX {
14
+ chat;
15
+ constructor(opts) {
16
+ this.chat = opts.chat;
17
+ }
18
+ newLatestChatsCursor(opts) {
19
+ return {
20
+ chat_room_id: opts.chat_room_id,
21
+ next_page: normalizePage(opts.page),
22
+ per_page: normalizePerPage(opts.per_page),
23
+ done: false,
24
+ };
25
+ }
26
+ async latestChats(opts) {
27
+ const page = normalizePage(opts.page);
28
+ const per_page = normalizePerPage(opts.per_page);
29
+ const raw = await this.chat.searchManyChats({
30
+ query: {
31
+ chat_room_id: opts.chat_room_id,
32
+ [SearchPageKey]: page,
33
+ [SearchPerPageKey]: per_page,
34
+ },
35
+ });
36
+ return latestChatsPage({
37
+ chat_room_id: opts.chat_room_id,
38
+ page,
39
+ per_page,
40
+ raw,
41
+ });
42
+ }
43
+ async nextLatestChats(opts) {
44
+ if (opts.cursor.done) {
45
+ return emptyLatestChatsPage(opts.cursor);
46
+ }
47
+ return await this.latestChats({
48
+ chat_room_id: opts.cursor.chat_room_id,
49
+ page: opts.cursor.next_page,
50
+ per_page: opts.cursor.per_page,
51
+ });
52
+ }
53
+ async chatRoomMembers(opts) {
54
+ const out = await this.chat.queryChatRoomMembers({
55
+ query: {
56
+ chat_room_id: opts.chat_room_id,
57
+ },
58
+ });
59
+ return out.value ?? [];
60
+ }
61
+ async myChatRoomMembers(opts) {
62
+ const out = await this.chat.queryChatRoomMembers({
63
+ query: {
64
+ owner_id: opts.owner_id,
65
+ },
66
+ });
67
+ return out.value ?? [];
68
+ }
69
+ async openChatRoom(opts) {
70
+ const latest = await this.latestChats({
71
+ chat_room_id: opts.chat_room_id,
72
+ per_page: opts.per_page,
73
+ });
74
+ const chats_ws = await this.chat.wsChats({
75
+ owner_id: opts.owner_id,
76
+ chat_room_id: opts.chat_room_id,
77
+ on_message: opts.on_chat,
78
+ on_error: opts.on_error,
79
+ on_close: opts.on_close,
80
+ });
81
+ const chat_room_ws = await this.chat.wsChatRoom({
82
+ id: opts.chat_room_id,
83
+ on_message: opts.on_chat_room,
84
+ on_error: opts.on_error,
85
+ on_close: opts.on_close,
86
+ });
87
+ return {
88
+ latest,
89
+ chats_ws,
90
+ chat_room_ws,
91
+ closeNormal(reason) {
92
+ closeWS([chats_ws, chat_room_ws], closeCodeNormal, reason);
93
+ },
94
+ closeLeavingPage(reason) {
95
+ closeWS([chats_ws, chat_room_ws], closeCodeLeavingPage, reason);
96
+ },
97
+ };
98
+ }
99
+ async openGlobalChatRooms(opts) {
100
+ const members = await this.myChatRoomMembers({
101
+ owner_id: opts.owner_id,
102
+ });
103
+ const chat_rooms_ws = await this.chat.wsMineChatRooms({
104
+ owner_id: opts.owner_id,
105
+ on_message: opts.on_chat_room,
106
+ on_error: opts.on_error,
107
+ on_close: opts.on_close,
108
+ });
109
+ return {
110
+ members,
111
+ chat_rooms_ws,
112
+ closeNormal(reason) {
113
+ closeWS([chat_rooms_ws], closeCodeNormal, reason);
114
+ },
115
+ closeLeavingPage(reason) {
116
+ closeWS([chat_rooms_ws], closeCodeLeavingPage, reason);
117
+ },
118
+ };
119
+ }
120
+ async reactUploadedChat(opts) {
121
+ if (opts.chat.has_objects && !opts.chat.objects_uploaded) {
122
+ throw errValidation({
123
+ field: "chat_id",
124
+ msg: msgChatObjectsUploading,
125
+ });
126
+ }
127
+ await this.chat.reactChat(opts.reaction);
128
+ }
129
+ }
130
+ export function newChatFX(opts) {
131
+ return new ChatFX(opts);
132
+ }
133
+ function latestChatsPage(opts) {
134
+ const value = opts.raw.value;
135
+ const chats = value?.[SearchResultResultsKey] ?? [];
136
+ const total_count = value?.total_count;
137
+ const last_page = value?.last_page;
138
+ const has_more = hasMoreChats({
139
+ chats,
140
+ page: opts.page,
141
+ per_page: opts.per_page,
142
+ total_count,
143
+ last_page,
144
+ });
145
+ return {
146
+ chats,
147
+ page: opts.page,
148
+ per_page: opts.per_page,
149
+ total_count,
150
+ last_page,
151
+ has_more,
152
+ next_cursor: {
153
+ chat_room_id: opts.chat_room_id,
154
+ next_page: has_more ? opts.page + 1 : opts.page,
155
+ per_page: opts.per_page,
156
+ done: !has_more,
157
+ },
158
+ };
159
+ }
160
+ function emptyLatestChatsPage(cursor) {
161
+ return {
162
+ chats: [],
163
+ page: cursor.next_page,
164
+ per_page: cursor.per_page,
165
+ has_more: false,
166
+ next_cursor: cursor,
167
+ };
168
+ }
169
+ function hasMoreChats(opts) {
170
+ if (opts.last_page !== undefined) {
171
+ return opts.page < opts.last_page;
172
+ }
173
+ if (opts.total_count !== undefined) {
174
+ return opts.page * opts.per_page < opts.total_count;
175
+ }
176
+ return opts.chats.length >= opts.per_page;
177
+ }
178
+ function closeWS(conns, code, reason) {
179
+ for (const conn of conns) {
180
+ conn.close(code, reason);
181
+ }
182
+ }
183
+ function normalizePage(v) {
184
+ if (v === undefined || !Number.isFinite(v)) {
185
+ return firstPage;
186
+ }
187
+ return Math.max(firstPage, Math.trunc(v));
188
+ }
189
+ function normalizePerPage(v) {
190
+ if (v === undefined || !Number.isFinite(v)) {
191
+ return defaultPerPage;
192
+ }
193
+ return Math.max(1, Math.trunc(v));
194
+ }
@@ -0,0 +1,67 @@
1
+ import { Friend, Hired, Manager, Na, OldHire, type Contact, type ID, type OperationResult } from "@fabriktor/schema";
2
+ import type { ContactsOperator } from "@fabriktor/client";
3
+ export type ContactRelation = typeof Na | typeof Friend | typeof OldHire | typeof Hired | typeof Manager;
4
+ export type ActiveContactRelation = typeof Friend | typeof Hired | typeof Manager;
5
+ export type ContactsFXOptions = {
6
+ contacts: ContactsOperator;
7
+ };
8
+ export type LoadContactIndexOptions = {
9
+ owner_id: string;
10
+ };
11
+ export type ContactIndex = {
12
+ contacts: Contact[];
13
+ peer_ids: Set<string>;
14
+ };
15
+ export type PresenceActiveHandler = (active_ids: ID[]) => void;
16
+ export type PresenceErrorHandler = (err: unknown) => void;
17
+ export type StartPresenceOptions = {
18
+ on_active: PresenceActiveHandler;
19
+ on_error?: PresenceErrorHandler;
20
+ };
21
+ export type PresenceSession = {
22
+ stop(): void;
23
+ };
24
+ export type SendFriendRequestOptions = {
25
+ contact_id: string;
26
+ };
27
+ export type RequestRelationUpgradeOptions = {
28
+ contact: Contact;
29
+ requested_relation: ActiveContactRelation;
30
+ };
31
+ export type DowngradeRelationOptions = {
32
+ contact: Contact;
33
+ relation: ActiveContactRelation;
34
+ };
35
+ export type AcceptContactRequestOptions = {
36
+ contact: Contact;
37
+ };
38
+ export type RejectContactRequestOptions = {
39
+ contact: Contact;
40
+ };
41
+ export type EndHireRelationOptions = {
42
+ contact: Contact;
43
+ };
44
+ export interface ContactsFXOperator {
45
+ loadContactIndex(opts: LoadContactIndexOptions): Promise<ContactIndex>;
46
+ startPresence(opts: StartPresenceOptions): Promise<PresenceSession>;
47
+ sendFriendRequest(opts: SendFriendRequestOptions): Promise<OperationResult>;
48
+ requestRelationUpgrade(opts: RequestRelationUpgradeOptions): Promise<OperationResult>;
49
+ downgradeRelation(opts: DowngradeRelationOptions): Promise<OperationResult>;
50
+ acceptContactRequest(opts: AcceptContactRequestOptions): Promise<OperationResult>;
51
+ rejectContactRequest(opts: RejectContactRequestOptions): Promise<OperationResult>;
52
+ endHireRelation(opts: EndHireRelationOptions): Promise<OperationResult>;
53
+ }
54
+ export declare class ContactsFX implements ContactsFXOperator {
55
+ private contacts;
56
+ constructor(opts: ContactsFXOptions);
57
+ loadContactIndex(opts: LoadContactIndexOptions): Promise<ContactIndex>;
58
+ startPresence(opts: StartPresenceOptions): Promise<PresenceSession>;
59
+ sendFriendRequest(opts: SendFriendRequestOptions): Promise<OperationResult>;
60
+ requestRelationUpgrade(opts: RequestRelationUpgradeOptions): Promise<OperationResult>;
61
+ downgradeRelation(opts: DowngradeRelationOptions): Promise<OperationResult>;
62
+ acceptContactRequest(opts: AcceptContactRequestOptions): Promise<OperationResult>;
63
+ rejectContactRequest(opts: RejectContactRequestOptions): Promise<OperationResult>;
64
+ endHireRelation(opts: EndHireRelationOptions): Promise<OperationResult>;
65
+ private replaceContact;
66
+ }
67
+ export declare function newContactsFX(opts: ContactsFXOptions): ContactsFX;