UNPKG

@vulog/aima-user

Version:

User management — profiles, personal information, labels, billing groups, and service registration.

499 lines (498 loc) 20.2 kB
import { z } from "zod"; import { createPaginableOptionsSchema } from "@vulog/aima-core"; //#region src/acceptTAndC.ts const schema$9 = z.object({ userId: z.string().uuid(), cityId: z.string().uuid() }); const acceptTAndC = async (client, userId, cityId) => { const result = schema$9.safeParse({ userId, cityId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.post(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/cities/${cityId}/users/${userId}/agreements`); }; //#endregion //#region src/assignBillingGroup.ts const schema$8 = z.object({ entityId: z.string().trim().min(1).uuid(), billingGroupId: z.string().trim().min(1).uuid() }); const assignBillingGroup = async (client, entityId, billingGroupId) => { const result = schema$8.safeParse({ entityId, billingGroupId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.post(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/billingGroup/${result.data.billingGroupId}/entities/${result.data.entityId}`); }; //#endregion //#region src/unassignBillingGroup.ts const schema$7 = z.object({ entityId: z.string().trim().min(1).uuid(), billingGroupId: z.string().trim().min(1).uuid() }); const unassignBillingGroup = async (client, entityId, billingGroupId) => { const result = schema$7.safeParse({ entityId, billingGroupId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.delete(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/billingGroup/${billingGroupId}/entities/${entityId}`); }; //#endregion //#region src/createBusinessProfile.ts const createBusinessProfileSchema = z.object({ userId: z.string().nonempty().uuid(), businessId: z.string().nonempty().uuid(), data: z.object({ emailConsent: z.boolean(), email: z.string().email(), requestId: z.string().nonempty().uuid(), costCenterId: z.string().uuid().nullish() }) }); /** @deprecated Use `addUserToBusiness` from `@vulog/aima-business` instead */ const createBusinessProfile = async (client, userId, businessId, data) => { const result = createBusinessProfileSchema.safeParse({ userId, businessId, data }); if (!result.success) throw new TypeError("Invalid arguments", { cause: result.error.issues }); return client.post(`/boapi/proxy/business/fleets/${client.clientOptions.fleetId}/business/${businessId}/user/${userId}`, result.data.data).then(({ data: p }) => p); }; //#endregion //#region src/createUser.ts const createUserSchema = z.object({ userName: z.string().min(1), password: z.string().min(1), locale: z.string().length(5), email: z.string().min(1).email(), dataPrivacyConsent: z.boolean().optional(), profilingConsent: z.boolean().optional(), marketingConsent: z.boolean().optional(), phoneNumber: z.string().optional() }); const createUserOptionsSchema = z.object({ tcApproval: z.boolean().default(true), skipUserNotification: z.boolean().default(false) }).default({ tcApproval: true, skipUserNotification: false }); const createUser = async (client, user, option) => { const resultUser = createUserSchema.safeParse(user); if (!resultUser.success) throw new TypeError("Invalid user", { cause: resultUser.error.issues }); const resultOptions = createUserOptionsSchema.safeParse(option); if (!resultOptions.success) throw new TypeError("Invalid options", { cause: resultOptions.error.issues }); const searchParams = new URLSearchParams(); searchParams.append("tcApproval", resultOptions.data.tcApproval.toString()); searchParams.append("skipUserNotification", resultOptions.data.skipUserNotification.toString()); return client.post(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/userDefault?${searchParams.toString()}`, resultUser.data).then(({ data }) => data); }; //#endregion //#region src/types.ts const accountStatus = [ "INCOMPLETE", "PENDING", "APPROVED", "REJECTED", "SUSPENDED", "ARCHIVED" ]; const personalInformationUserTypes = [ "IDENTITY", "USERNAME", "BIRTH", "NATIONALITY", "NOTES", "GENDER", "PERSONAL_COMPANY", "FISCAL", "ADDRESS", "MEMBERSHIP" ]; const personalInformationUserPaths = [ "/identity/firstName", "/identity/lastName", "/identity/middleName", "/identity/preferredName", "/birth/birthDate", "/birth/countryBirth", "/birth/provinceBirth", "/birth/cityBirth", "/nationality", "/notes", "/gender", "/personalCompany/companyName", "/personalCompany/companyVat", "/personalCompany/companyAddress/streetName", "/personalCompany/companyAddress/city", "/personalCompany/companyAddress/postalCode", "/personalCompany/companyAddress/region", "/personalCompany/companyAddress/country", "/personalCompany/companyAddress/number", "/personalCompany/companyAddress/addressAdditionalInformation", "/fiscalInformation/fiscal", "/fiscalInformation/personalVatNumber", "/fiscalInformation/sdi", "/fiscalInformation/pecAddress", "/fiscalInformation/marketReference", "/address/streetName", "/address/city", "/address/postalCode", "/address/region", "/address/country", "/address/number", "/address/addressAdditionalInformation", "/membership" ]; const personalInformationUserTypeSchema = z.enum(personalInformationUserTypes); const personalInformationProfileTypes = [ "ID_NUMBER", "PHONE_NUMBER", "EMAIL", "BILLING_ADDRESS" ]; const personalInformationProfileTypeSchema = z.enum(personalInformationProfileTypes); //#endregion //#region src/findUser.ts const querySchema = z.object({ searchType: z.enum([ "email", "username", "phoneNumber" ]), searchQuery: z.string().min(1), types: z.array(personalInformationUserTypeSchema).min(1) }); const findUser = async (client, searchType, searchQuery, types) => { const result = querySchema.safeParse({ searchType, searchQuery, types }); if (!result.success) throw new TypeError("Invalid arguments", { cause: result.error.issues }); return client.post(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/pi/find?types=${result.data.types.join(",")}`, { [result.data.searchType]: result.data.searchQuery }).then(({ data }) => data); }; //#endregion //#region src/getProfilePersonalInfoById.ts const argsSchema$3 = z.object({ userId: z.string().trim().min(1).uuid(), profileId: z.string().trim().min(1).uuid(), types: z.array(personalInformationProfileTypeSchema).min(1) }); const getProfilePersonalInfoById = async (client, userId, profileId, types) => { const result = argsSchema$3.safeParse({ userId, profileId, types }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${result.data.userId}/profiles/${result.data.profileId}/pi?types=${result.data.types.join(",")}`).then(({ data }) => data); }; //#endregion //#region src/getRegistrationOverview.ts const getRegistrationOverview = async (client, userId) => { const result = z.string().uuid().safeParse(userId); if (!result.success) throw new TypeError("Invalid userId", { cause: result.error.issues }); return client.get(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${userId}/services`).then(({ data: { userId: _, ...data } }) => data); }; //#endregion //#region src/getUserById.ts const getUserById = async (client, id, addAccountStatus = false) => { const result = z.string().trim().min(1).uuid().safeParse(id); if (!result.success) throw new TypeError("Invalid id", { cause: result.error.issues }); const user = await client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${id}/status`).then(({ data }) => data); if (addAccountStatus) user.accountStatus = await client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${id}`).then(({ data: { accountStatus } }) => accountStatus); return user; }; //#endregion //#region src/getUserByEmail.ts const getUserByEmail = async (client, email) => { const result = z.string().trim().min(1).email().safeParse(email); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/usernames/${encodeURIComponent(result.data)}`).then(({ data }) => data); }; //#endregion //#region src/getUserPersonalInfoById.ts const argsSchema$2 = z.object({ id: z.string().trim().min(1).uuid(), types: z.array(personalInformationUserTypeSchema).min(1) }); const getUserPersonalInfoById = async (client, id, types) => { const result = argsSchema$2.safeParse({ id, types }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${result.data.id}/pi?types=${result.data.types.join(",")}`).then(({ data }) => data); }; //#endregion //#region src/getUsersPIByIds.ts const argsSchema$1 = z.object({ ids: z.array(z.string().trim().min(1).uuid()).min(1), types: z.array(personalInformationUserTypeSchema).min(1) }); const getUsersPIByIds = async (client, ids, types) => { const result = argsSchema$1.safeParse({ ids, types }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.post(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/pi/list?${result.data.types.map((type) => `types=${type}`).join("&")}`, { userIds: result.data.ids }).then(({ data }) => data.content); }; //#endregion //#region src/label.ts const schema$6 = z.object({ userId: z.string().uuid() }); const schemaData = z.object({ userId: z.string().uuid(), labelId: z.number().positive() }); const getLabelsForUser = async (client, userId) => { const result = schema$6.safeParse({ userId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.get(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${userId}/userLabels`).then(({ data }) => data); }; const addLabelForUser = async (client, userId, labelId) => { const result = schemaData.safeParse({ userId, labelId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.post(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${userId}/userLabels`, { labelId }); }; const removeLabelForUser = async (client, userId, labelId) => { const result = schemaData.safeParse({ userId, labelId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.delete(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${userId}/userLabels/${labelId}`); }; //#endregion //#region src/setServicesStatus.ts const schema$5 = z.object({ disableEmailNotification: z.boolean(), operatorProfileId: z.string().uuid(), actions: z.array(z.object({ reasonForChange: z.string(), serviceId: z.string().uuid(), status: z.enum([ "APPROVED", "INCOMPLETE", "PENDING", "REJECTED", "SUSPENDED", "UNREGISTERED" ]) })).min(1) }); const setServicesStatus = async (client, profileId, servicesUpdate) => { const resultProfileId = z.string().uuid().safeParse(profileId); if (!resultProfileId.success) throw new TypeError("Invalid profileId", { cause: resultProfileId.error.issues }); const resultServices = schema$5.safeParse(servicesUpdate); if (!resultServices.success) throw new TypeError("Invalid servicesUpdate", { cause: resultServices.error.issues }); await client.post(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/profiles/${profileId}/serviceRegistrations`, servicesUpdate); }; //#endregion //#region src/registerUserToService.ts const registerUserToService = async (client, entityId, serviceId) => { const resultEntityId = z.string().uuid().safeParse(entityId); if (!resultEntityId.success) throw new TypeError("Invalid entityId", { cause: resultEntityId.error.issues }); const resultServiceId = z.string().uuid().safeParse(serviceId); if (!resultServiceId.success) throw new TypeError("Invalid serviceId", { cause: resultServiceId.error.issues }); await client.put(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/entities/${entityId}/services/${serviceId}`); }; //#endregion //#region src/updateProfilePersonalInfo.ts const paths = [ "/phoneNumber", "/email", "/idNumber" ]; const schema$4 = z.object({ userId: z.string().trim().min(1).uuid(), profileId: z.string().trim().min(1).uuid(), actions: z.array(z.union([z.object({ op: z.enum(["add", "replace"]), path: z.enum(paths), value: z.string().min(1) }), z.object({ op: z.literal("remove"), path: z.enum(paths) })])).min(1) }); const updateProfilePersonalInfo = async (client, userId, profileId, actions) => { const result = schema$4.safeParse({ userId, profileId, actions }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.patch(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${userId}/profiles/${profileId}/pi`, actions, { headers: { "Content-Type": "application/json-patch+json" } }); }; //#endregion //#region src/updateUser.ts const schema$3 = z.object({ id: z.string().trim().min(1).uuid(), user: z.object({ locale: z.string(), accountStatus: z.enum(accountStatus), dataPrivacyConsent: z.boolean(), marketingConsent: z.boolean(), surveyConsent: z.boolean(), shareDataConsent: z.boolean(), profilingConsent: z.boolean(), membershipNumber: z.string() }).partial() }); const updateUser = async (client, id, user) => { const result = schema$3.safeParse({ id, user }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.post(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${id}`, user).then(({ data }) => data); }; //#endregion //#region src/updateUserPersonalInfo.ts const schema$2 = z.object({ userId: z.string().trim().min(1).uuid(), actions: z.array(z.union([z.object({ op: z.enum(["add", "replace"]), path: z.enum(personalInformationUserPaths), value: z.string().min(1) }), z.object({ op: z.literal("remove"), path: z.enum(personalInformationUserPaths) })])).min(1) }); const updateUserPersonalInfo = async (client, userId, actions) => { const result = schema$2.safeParse({ userId, actions }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); await client.patch(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/${userId}/pi`, actions, { headers: { "Content-Type": "application/json-patch+json" } }).then(({ data }) => data); }; //#endregion //#region src/getEntity.ts const getEntity = async (client, entityId) => { const result = z.string().trim().min(1).uuid().safeParse(entityId); if (!result.success) throw new TypeError("Invalid entity id", { cause: result.error.issues }); return await client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/entities/${entityId}`).then(({ data }) => data); }; //#endregion //#region src/getFleetBillingGroups.ts const getFleetBillingGroups = async (client, options) => { const resultOptions = createPaginableOptionsSchema().safeParse(options ?? {}); if (!resultOptions.success) throw new TypeError("Invalid options", { cause: resultOptions.error.issues }); const finalOptions = resultOptions.data; const searchParams = new URLSearchParams(); searchParams.append("page", finalOptions.page.toString()); searchParams.append("size", finalOptions.pageSize.toString()); return client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/billingGroup?${searchParams.toString()}`).then(({ data, headers }) => { return { data, page: headers.number, pageSize: headers.size, total: headers.totalelements, totalPages: headers.totalpages }; }).catch((error) => { throw new Error(`Failed to get fleet billing groups: ${error.message}`); }); }; //#endregion //#region src/getUsersByIds.ts const argsSchema = z.object({ ids: z.array(z.string().trim().min(1).uuid()).min(1) }); const getUsersByIds = async (client, ids) => { const result = argsSchema.safeParse({ ids }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.post(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users/list`, result.data.ids).then(({ data }) => data); }; //#endregion //#region src/getUsers.ts const statusSchema = z.enum([ "PENDING", "INCOMPLETE", "SUSPENDED", "REJECTED", "APPROVED" ]); const profileTypeSchema = z.enum(["Single", "Business"]); const userFiltersSchema = z.object({ status: statusSchema.optional(), profileType: profileTypeSchema.optional(), serviceId: z.string().uuid().optional() }); const sortSchema = z.enum([ "registrationDate", "userName", "firstName", "lastName", "updateDate" ]); const getUsers = async (client, options) => { const resultOptions = createPaginableOptionsSchema(userFiltersSchema.default({}), sortSchema.optional().default("registrationDate")).safeParse(options ?? {}); if (!resultOptions.success) throw new TypeError("Invalid options", { cause: resultOptions.error.issues }); const finalOptions = resultOptions.data; const searchParams = new URLSearchParams(); searchParams.append("page", finalOptions.page.toString()); searchParams.append("size", finalOptions.pageSize.toString()); searchParams.append("sort", `${finalOptions.sort.toString()},${finalOptions.sortDirection.toString()}`); Object.entries(finalOptions.filters).forEach(([key, value]) => { if (value === void 0) return; searchParams.append(key, value); }); return client.get(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users?${searchParams.toString()}`).then(({ data, headers }) => { return { data, page: headers.number, pageSize: headers.size, total: headers.totalelements, totalPages: headers.totalpages }; }); }; //#endregion //#region src/getServiceRegistrationOverview.ts const schema$1 = z.array(z.string().uuid()).min(1); /** * Get an overview of the service registration statuses for a list of userIds. * * Swagger: `GET /fleets/{fleetId}/serviceRegistrationOverview` (admin-user, * operationId `getServicesRegistrationOverview`). */ const getServiceRegistrationOverview = async (client, userIds) => { const result = schema$1.safeParse(userIds); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); const searchParams = new URLSearchParams(); for (const id of result.data) searchParams.append("userId", id); return client.get(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/serviceRegistrationOverview?${searchParams.toString()}`).then(({ data }) => data); }; //#endregion //#region src/requestServiceRegistration.ts const schema = z.object({ profileId: z.string().uuid(), serviceId: z.string().uuid() }); /** * Register a user profile to a service. * * Swagger: `PUT /fleets/{fleetId}/profiles/{profileId}/services/{id}` (admin-user, * operationId `requestServiceRegistration`). */ const requestServiceRegistration = async (client, profileId, serviceId) => { const result = schema.safeParse({ profileId, serviceId }); if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues }); return client.put(`boapi/proxy/user/fleets/${client.clientOptions.fleetId}/profiles/${result.data.profileId}/services/${result.data.serviceId}`).then(({ data }) => data); }; //#endregion export { acceptTAndC, accountStatus, addLabelForUser, assignBillingGroup, createBusinessProfile, createUser, findUser, getEntity, getFleetBillingGroups, getLabelsForUser, getProfilePersonalInfoById, getRegistrationOverview, getServiceRegistrationOverview, getUserByEmail, getUserById, getUserPersonalInfoById, getUsers, getUsersByIds, getUsersPIByIds, personalInformationProfileTypeSchema, personalInformationProfileTypes, personalInformationUserPaths, personalInformationUserTypeSchema, personalInformationUserTypes, registerUserToService, removeLabelForUser, requestServiceRegistration, setServicesStatus, unassignBillingGroup, updateProfilePersonalInfo, updateUser, updateUserPersonalInfo };