Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { http } from '@amalia/core/http/client';
import { bufferCalls } from '@amalia/ext/typescript';
import { type AuthenticatedContext, type AuthenticatedContextDto } from '@amalia/kernel/auth/types';
import { AdminScopesContainer } from '@amalia/tenants/companies/admin-scopes/shared';
import { HierarchyContext } from '@amalia/tenants/teams/hierarchy/shared';
import {
type BulkSyncUsersRequest,
type ImpersonateUserRequest,
type KeysOfUserWithStringValues,
type ListUsersRequest,
type SyncUserRequest,
type UserComputed,
type UserContract,
type UserRole,
type UserSettings,
} from '@amalia/tenants/users/types';
const SEARCH_PARAM_NAME_BY_PROPERTY = {
id: 'ids',
externalId: 'externalIds',
email: 'emails',
} as const satisfies Record<string, string>;
export class UserApiClient {
// FIXME(clean): Should be moved to some DateValueObject I guess?
public static mapDateFromApi(date: Date | string): Date;
public static mapDateFromApi(date?: Date | null): Date | null;
public static mapDateFromApi(date?: Date | string | null): Date | null {
return date ? new Date(date) : null;
}
public static mapUserFromApi(user: UserContract): UserContract {
return {
...user,
lastConnection: this.mapDateFromApi(user.lastConnection),
createdAt: this.mapDateFromApi(user.createdAt),
updatedAt: this.mapDateFromApi(user.updatedAt),
joinedAt: this.mapDateFromApi(user.joinedAt),
invitationSentAt: this.mapDateFromApi(user.invitationSentAt),
clearedAt: this.mapDateFromApi(user.clearedAt),
};
}
public static async fetchUserBy(property: KeysOfUserWithStringValues, value: string): Promise<UserComputed | null> {
const searchParamName =
property in SEARCH_PARAM_NAME_BY_PROPERTY
? SEARCH_PARAM_NAME_BY_PROPERTY[property as keyof typeof SEARCH_PARAM_NAME_BY_PROPERTY]
: SEARCH_PARAM_NAME_BY_PROPERTY.externalId;
const { data } = await http.post<UserComputed[]>('/users/searches', {
[searchParamName]: [value],
} satisfies ListUsersRequest);
return data.length ? data[0] : null;
}
public static readonly bufferedFetchUserBy = bufferCalls<
[property: KeysOfUserWithStringValues, value: string],
UserContract | null,
UserContract[]
>(
async (bufferedArgs) => {
const params = bufferedArgs.reduce<
Record<(typeof SEARCH_PARAM_NAME_BY_PROPERTY)[keyof typeof SEARCH_PARAM_NAME_BY_PROPERTY], Set<string>>
>(
(acc, [property, value]) => {
const searchParamName =
property in SEARCH_PARAM_NAME_BY_PROPERTY
? SEARCH_PARAM_NAME_BY_PROPERTY[property as keyof typeof SEARCH_PARAM_NAME_BY_PROPERTY]
: SEARCH_PARAM_NAME_BY_PROPERTY.externalId;
acc[searchParamName].add(value);
return acc;
},
{ ids: new Set(), externalIds: new Set(), emails: new Set() },
);
const { data } = await http.post<UserContract[]>('/users/searches', {
ids: Array.from(params.ids),
externalIds: Array.from(params.externalIds),
emails: Array.from(params.emails),
} satisfies ListUsersRequest);
return data;
},
([property, value], result) => result.find((user) => user[property] === value) ?? null,
);
public static async fetchAllUsers(): Promise<UserContract[]> {
const { data } = await http.post<UserContract[]>('/users/searches');
return data;
}
public static async fetchAuthenticatedContext(): Promise<AuthenticatedContext> {
const {
data: { hierarchyContextDehydrated, adminScopesContainerDehydrated, user, ...data },
} = await http.get<AuthenticatedContextDto>('/users/me');
return {
...data,
user: this.mapUserFromApi(user),
hierarchy: HierarchyContext.hydrate(user, hierarchyContextDehydrated),
adminScopesContainer: adminScopesContainerDehydrated
? AdminScopesContainer.hydrate(adminScopesContainerDehydrated)
: undefined,
login: data.login
? { previousLastConnection: this.mapDateFromApi(data.login.previousLastConnection) }
: undefined,
};
}
public static async getEmployees(): Promise<UserContract[]> {
const { data } = await http.post<UserContract[]>('/users/searches');
return data;
}
public static async logout(): Promise<void> {
await http.patch('/users/logout');
}
public static async updateSettings(settings: UserSettings): Promise<UserContract> {
const { data } = await http.patch<UserContract>('/users/settings', settings);
return data;
}
public static async fetchUsersByIds(userIds: string[]): Promise<UserContract[]> {
const { data } = await http.post<UserContract[]>('/users/searches', { ids: userIds } satisfies ListUsersRequest);
return data;
}
public static async fetchActiveUsers(): Promise<UserContract[]> {
const { data } = await http.post<UserContract[]>('/users/searches', { active: true } satisfies ListUsersRequest);
return data;
}
public static async bulkSyncUsers(users: SyncUserRequest[]): Promise<void> {
await http.post('/users/registrations', { users } as BulkSyncUsersRequest);
}
public static async impersonate({ userIdToImpersonate }: { userIdToImpersonate: string | null }): Promise<void> {
await http.patch(`/users/impersonate`, { userIdToImpersonate } satisfies ImpersonateUserRequest);
}
public static async resetImpersonate(): Promise<void> {
await http.patch(`/users/impersonate`, { userIdToImpersonate: null } satisfies ImpersonateUserRequest);
}
public static async getUserManagers({
userId,
...rest
}: {
userId: UserContract['id'];
startDate: number;
endDate: number;
filterByUserRoles: UserRole[];
withParents: boolean;
}): Promise<UserContract[]> {
const { data } = await http.get<UserContract[]>(`/users/${encodeURIComponent(userId)}/managers`, {
params: {
...rest,
},
});
return data;
}
}
|