@intlayer/backend 8.10.0-canary.0 → 8.10.0-canary.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/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/dictionary/markdown.json +1 -8945
- package/dist/esm/controllers/ai.controller.mjs +2 -2
- package/dist/esm/controllers/ai.controller.mjs.map +1 -1
- package/dist/esm/services/audit/recursiveAudit.service.mjs +1 -1
- package/dist/esm/services/audit/recursiveAudit.service.mjs.map +1 -1
- package/dist/esm/services/cliSessionToken.service.mjs +2 -2
- package/dist/esm/services/cliSessionToken.service.mjs.map +1 -1
- package/dist/esm/services/dictionary.service.mjs +1 -1
- package/dist/esm/services/dictionary.service.mjs.map +1 -1
- package/dist/esm/services/oAuth2.service.mjs +3 -3
- package/dist/esm/services/oAuth2.service.mjs.map +1 -1
- package/dist/esm/services/projectAccessKey.service.mjs +2 -2
- package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
- package/dist/esm/services/showcase/showcaseProject.service.mjs +1 -1
- package/dist/esm/services/showcase/showcaseProject.service.mjs.map +1 -1
- package/dist/esm/services/user.service.mjs +1 -1
- package/dist/esm/services/user.service.mjs.map +1 -1
- package/dist/esm/utils/AI/askDocQuestion/embeddings/docs/en/dictionary/markdown.json +1 -8945
- package/dist/types/schemas/dictionary.schema.d.ts +9 -9
- package/dist/types/schemas/discussion.schema.d.ts +7 -7
- package/dist/types/schemas/organization.schema.d.ts +8 -8
- package/dist/types/schemas/plans.schema.d.ts +4 -4
- package/dist/types/schemas/project.schema.d.ts +11 -11
- package/dist/types/schemas/showcaseProject.schema.d.ts +18 -18
- package/dist/types/schemas/tag.schema.d.ts +9 -9
- package/dist/types/schemas/user.schema.d.ts +8 -8
- package/dist/types/services/showcase/showcaseProject.service.d.ts.map +1 -1
- package/dist/types/utils/errors/ErrorHandler.d.ts +4 -4
- package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +4 -4
- package/package.json +14 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"showcaseProject.service.mjs","names":[],"sources":["../../../../src/services/showcase/showcaseProject.service.ts"],"sourcesContent":["import { ShowcaseProjectModel } from '@models/showcaseProject.model';\nimport { GenericError } from '@utils/errors';\nimport type {\n ShowcaseProjectData,\n ShowcaseProjectDocument,\n ShowcaseProjectStatus,\n} from '@/types/showcaseProject.types';\n\nexport const findShowcaseProjects = async (filters: {\n search?: string;\n selectedUseCases?: string[];\n isOpenSource?: boolean;\n page?: number;\n pageSize?: number;\n}): Promise<{\n data: ShowcaseProjectDocument[];\n total_items: number;\n total_pages: number;\n}> => {\n const {\n search,\n selectedUseCases,\n isOpenSource,\n page = 1,\n pageSize = 20,\n } = filters;\n\n const query: Record<string, unknown> = {};\n\n if (isOpenSource) {\n query.githubUrl = { $exists: true, $ne: null };\n }\n if (selectedUseCases && selectedUseCases.length > 0) {\n query.tags = { $in: selectedUseCases };\n }\n if (search?.trim()) {\n query.$or = [\n { title: { $regex: search, $options: 'i' } },\n { description: { $regex: search, $options: 'i' } },\n { tags: { $regex: search, $options: 'i' } },\n ];\n }\n\n const total_items = await ShowcaseProjectModel.countDocuments(query);\n const total_pages = Math.ceil(total_items / pageSize) || 1;\n\n const data = await ShowcaseProjectModel.aggregate([\n { $match: query },\n {\n $addFields: {\n score: {\n $subtract: [\n { $size: { $ifNull: ['$upvoters', []] } },\n { $size: { $ifNull: ['$downvoters', []] } },\n ],\n },\n },\n },\n { $sort: { score: -1, createdAt: -1 } },\n { $skip: (page - 1) * pageSize },\n { $limit: pageSize },\n ]);\n\n return {\n data: data as unknown as ShowcaseProjectDocument[],\n total_items,\n total_pages,\n };\n};\n\nexport const findShowcaseProjectById = async (\n projectId: string\n): Promise<ShowcaseProjectDocument> => {\n const project = await ShowcaseProjectModel.findById(projectId).lean();\n\n if (!project) {\n throw new GenericError('SHOWCASE_PROJECT_NOT_FOUND', { projectId });\n }\n\n return project as unknown as ShowcaseProjectDocument;\n};\n\n/**\n * Finds an existing project whose websiteUrl shares the same hostname as the\n * given URL. This treats `example.com` and `example.com/path` as duplicates\n * while allowing `sub.example.com` as a distinct entry.\n */\nexport const findShowcaseProjectByUrl = async (\n websiteUrl: string\n): Promise<ShowcaseProjectDocument | null> => {\n let hostname: string;\n try {\n hostname = new URL(websiteUrl).hostname;\n } catch {\n // Fallback to exact match if URL is unparseable\n const project = await ShowcaseProjectModel.findOne({ websiteUrl
|
|
1
|
+
{"version":3,"file":"showcaseProject.service.mjs","names":[],"sources":["../../../../src/services/showcase/showcaseProject.service.ts"],"sourcesContent":["import { ShowcaseProjectModel } from '@models/showcaseProject.model';\nimport { GenericError } from '@utils/errors';\nimport type {\n ShowcaseProjectData,\n ShowcaseProjectDocument,\n ShowcaseProjectStatus,\n} from '@/types/showcaseProject.types';\n\nexport const findShowcaseProjects = async (filters: {\n search?: string;\n selectedUseCases?: string[];\n isOpenSource?: boolean;\n page?: number;\n pageSize?: number;\n}): Promise<{\n data: ShowcaseProjectDocument[];\n total_items: number;\n total_pages: number;\n}> => {\n const {\n search,\n selectedUseCases,\n isOpenSource,\n page = 1,\n pageSize = 20,\n } = filters;\n\n const query: Record<string, unknown> = {};\n\n if (isOpenSource) {\n query.githubUrl = { $exists: true, $ne: null };\n }\n if (selectedUseCases && selectedUseCases.length > 0) {\n query.tags = { $in: selectedUseCases };\n }\n if (search?.trim()) {\n query.$or = [\n { title: { $regex: search, $options: 'i' } },\n { description: { $regex: search, $options: 'i' } },\n { tags: { $regex: search, $options: 'i' } },\n ];\n }\n\n const total_items = await ShowcaseProjectModel.countDocuments(query);\n const total_pages = Math.ceil(total_items / pageSize) || 1;\n\n const data = await ShowcaseProjectModel.aggregate([\n { $match: query },\n {\n $addFields: {\n score: {\n $subtract: [\n { $size: { $ifNull: ['$upvoters', []] } },\n { $size: { $ifNull: ['$downvoters', []] } },\n ],\n },\n },\n },\n { $sort: { score: -1, createdAt: -1 } },\n { $skip: (page - 1) * pageSize },\n { $limit: pageSize },\n ]);\n\n return {\n data: data as unknown as ShowcaseProjectDocument[],\n total_items,\n total_pages,\n };\n};\n\nexport const findShowcaseProjectById = async (\n projectId: string\n): Promise<ShowcaseProjectDocument> => {\n const project = await ShowcaseProjectModel.findById(projectId).lean();\n\n if (!project) {\n throw new GenericError('SHOWCASE_PROJECT_NOT_FOUND', { projectId });\n }\n\n return project as unknown as ShowcaseProjectDocument;\n};\n\n/**\n * Finds an existing project whose websiteUrl shares the same hostname as the\n * given URL. This treats `example.com` and `example.com/path` as duplicates\n * while allowing `sub.example.com` as a distinct entry.\n */\nexport const findShowcaseProjectByUrl = async (\n websiteUrl: string\n): Promise<ShowcaseProjectDocument | null> => {\n let hostname: string;\n try {\n hostname = new URL(websiteUrl).hostname;\n } catch {\n // Fallback to exact match if URL is unparseable\n const project = await ShowcaseProjectModel.findOne({\n websiteUrl: String(websiteUrl),\n }).lean();\n return project as unknown as ShowcaseProjectDocument | null;\n }\n\n // Match any stored URL whose authority (scheme + hostname) equals this hostname.\n // Anchored after the scheme so sub.example.com does NOT match example.com.\n const hostnameRegex = new RegExp(\n `^https?://${hostname.replace(/\\./g, '\\\\.')}(/|$)`,\n 'i'\n );\n const project = await ShowcaseProjectModel.findOne({\n websiteUrl: { $regex: hostnameRegex },\n }).lean();\n return project as unknown as ShowcaseProjectDocument | null;\n};\n\nexport const findOtherShowcaseProjects = async (\n excludeId: string,\n limit = 4\n): Promise<ShowcaseProjectDocument[]> => {\n const projects = await ShowcaseProjectModel.find({\n _id: { $ne: excludeId },\n })\n .limit(limit)\n .lean();\n\n return projects as unknown as ShowcaseProjectDocument[];\n};\n\nexport const createShowcaseProject = async (\n projectData: ShowcaseProjectData\n): Promise<ShowcaseProjectDocument> => {\n const newProject = new ShowcaseProjectModel({\n ...projectData,\n ...projectData,\n upvoters: [],\n downvoters: [],\n });\n\n await newProject.save();\n return newProject as unknown as ShowcaseProjectDocument;\n};\n\nexport type UpdateShowcaseProjectScanData = {\n title?: string;\n description?: string;\n websiteUrl?: string;\n githubUrl?: string | null;\n tags?: string[];\n intlayerVersion?: string;\n libsUsed?: string[];\n packageDetails?: Record<string, string>;\n scanDetails?: ShowcaseProjectData['scanDetails'];\n imageUrl?: string;\n isOpenSource?: boolean;\n status?: ShowcaseProjectStatus;\n lastScanDate?: Date;\n};\n\nexport const updateShowcaseProject = async (\n projectId: string,\n updates: UpdateShowcaseProjectScanData\n): Promise<ShowcaseProjectDocument> => {\n const project = await ShowcaseProjectModel.findByIdAndUpdate(\n projectId,\n { $set: updates },\n { new: true }\n ).lean();\n\n if (!project) {\n throw new GenericError('SHOWCASE_PROJECT_NOT_FOUND', { projectId });\n }\n\n return project as unknown as ShowcaseProjectDocument;\n};\n\nexport const deleteShowcaseProject = async (\n projectId: string\n): Promise<void> => {\n await ShowcaseProjectModel.findByIdAndDelete(projectId);\n};\n\ntype VoteResult = {\n upvotes: number;\n isUpVoted: boolean;\n downvotes: number;\n isDownVoted: boolean;\n};\n\nconst toggleShowcaseVote = async (\n projectId: string,\n userId: string,\n voteType: 'up' | 'down'\n): Promise<VoteResult> => {\n const project = await ShowcaseProjectModel.findById(projectId);\n\n if (!project) {\n throw new GenericError('SHOWCASE_PROJECT_NOT_FOUND', { projectId });\n }\n\n const upvoters: string[] = project.upvoters || [];\n const downvoters: string[] = project.downvoters || [];\n\n if (voteType === 'up') {\n const wasUpvoted = upvoters.includes(userId);\n\n if (wasUpvoted) {\n project.upvoters = upvoters.filter((id) => id !== userId);\n } else {\n project.upvoters.push(userId);\n if (downvoters.includes(userId)) {\n project.downvoters = downvoters.filter((id) => id !== userId);\n }\n }\n\n await project.save();\n\n return {\n upvotes: project.upvoters.length,\n isUpVoted: !wasUpvoted,\n downvotes: project.downvoters.length,\n isDownVoted: false,\n };\n } else {\n const wasDownvoted = downvoters.includes(userId);\n\n if (wasDownvoted) {\n project.downvoters = downvoters.filter((id) => id !== userId);\n } else {\n project.downvoters.push(userId);\n\n if (upvoters.includes(userId)) {\n project.upvoters = upvoters.filter((id) => id !== userId);\n }\n }\n await project.save();\n return {\n upvotes: project.upvoters.length,\n isUpVoted: false,\n downvotes: project.downvoters.length,\n isDownVoted: !wasDownvoted,\n };\n }\n};\n\nexport const toggleShowcaseUpvote = (\n projectId: string,\n userId: string\n): Promise<VoteResult> => toggleShowcaseVote(projectId, userId, 'up');\n\nexport const toggleShowcaseDownvote = (\n projectId: string,\n userId: string\n): Promise<VoteResult> => toggleShowcaseVote(projectId, userId, 'down');\n"],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ const createUser = async (user) => {
|
|
|
24
24
|
* @returns User object or null if no user was found.
|
|
25
25
|
*/
|
|
26
26
|
const getUserByEmail = async (email) => {
|
|
27
|
-
return await UserModel.findOne({ email });
|
|
27
|
+
return await UserModel.findOne({ email: String(email) });
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
30
|
* Retrieves users list by email.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.service.mjs","names":[],"sources":["../../../src/services/user.service.ts"],"sourcesContent":["import { UserModel } from '@models/user.model';\nimport { GenericError } from '@utils/errors';\nimport type { UserFilters } from '@utils/filtersAndPagination/getUserFiltersAndPagination';\nimport {\n type FieldsToCheck,\n type UserFields,\n validateUser,\n} from '@utils/validation/validateUser';\nimport type { Types } from 'mongoose';\nimport type { User, UserAPI, UserDocument } from '@/types/user.types';\n\n/**\n * Creates a new user with password in the database and hashes the password.\n * @param user - User object with password not hashed.\n * @returns Created user object.\n */\nexport const createUser = async (\n user: Partial<User>\n): Promise<UserDocument> => {\n const fieldsToCheck: FieldsToCheck[] = ['email'];\n\n const errors = validateUser(user, fieldsToCheck);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userEmail: user.email,\n errors,\n });\n }\n\n const newUser: UserDocument = await UserModel.create(user);\n\n if (!newUser) {\n throw new GenericError('USER_CREATION_FAILED', { userEmail: user.email });\n }\n\n return newUser;\n};\n\n/**\n * Retrieves a user by email.\n * @param email - User's email.\n * @returns User object or null if no user was found.\n */\nexport const getUserByEmail = async (\n email: string\n): Promise<UserDocument | null> => {\n return await UserModel.findOne({ email });\n};\n\n/**\n * Retrieves users list by email.\n * @param emails - Users email.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByEmails = async (\n emails: string[]\n): Promise<UserDocument[] | null> => {\n return await UserModel.find({ email: { $in: emails } });\n};\n\n/**\n * Checks if a user exists by email.\n * @param email - User's email.\n * @returns True if the user exists, false otherwise.\n */\nexport const checkUserExists = async (email: string): Promise<boolean> => {\n const user = await UserModel.exists({ email });\n return user !== null;\n};\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUserById = async (\n userId: string | Types.ObjectId\n): Promise<UserDocument | null> => await UserModel.findById(userId);\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByIds = async (\n userIds: (string | Types.ObjectId)[]\n): Promise<UserDocument[] | null> =>\n await UserModel.find({ _id: { $in: userIds } });\n\n/**\n * Finds users based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @param sortOptions - Sorting options.\n * @returns List of users matching the filters.\n */\nexport const findUsers = async (\n filters: UserFilters,\n skip: number,\n limit: number,\n sortOptions?: Record<string, 1 | -1>\n): Promise<UserDocument[]> => {\n let query = UserModel.find(filters).skip(skip).limit(limit);\n\n if (sortOptions && Object.keys(sortOptions).length > 0) {\n query = query.sort(sortOptions);\n }\n\n return await query;\n};\n\n/**\n * Counts the total number of users that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of users.\n */\nexport const countUsers = async (filters: UserFilters): Promise<number> => {\n const count = await UserModel.countDocuments(filters);\n\n if (typeof count === 'undefined') {\n throw new GenericError('USER_COUNT_FAILED');\n }\n\n return count;\n};\n\n/**\n * Updates a user's information.\n * @param user - The user object.\n * @param updates - The updates to apply to the user.\n * @returns The updated user.\n */\nexport const updateUserById = async (\n userId: string | Types.ObjectId,\n updates: Partial<UserAPI>\n): Promise<UserDocument> => {\n const { id, ...updatesWithoutId } = updates;\n\n const keyToValidate = Object.keys(updatesWithoutId) as UserFields;\n const errors = validateUser(updatesWithoutId, keyToValidate);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userId,\n errors,\n });\n }\n\n const result = await UserModel.updateOne(\n { _id: userId },\n { $set: updatesWithoutId }\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('USER_UPDATE_FAILED', { userId });\n }\n\n const updatedUser = await UserModel.findById(userId);\n\n if (!updatedUser) {\n throw new GenericError('USER_UPDATED_USER_NOT_FOUND', { userId });\n }\n\n return updatedUser;\n};\n\n/**\n * Deletes a user from the database.\n * @param userId - The user object.\n * @returns\n */\nexport const deleteUser = async (\n userId: string | Types.ObjectId\n): Promise<UserDocument> => {\n await getUserById(userId);\n\n const user = await UserModel.findByIdAndDelete(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n return user;\n};\n"],"mappings":";;;;;;;;;;AAgBA,MAAa,aAAa,OACxB,SAC0B;CAG1B,MAAM,SAAS,aAAa,MAAM,CAFM,OAEM,CAAC;CAE/C,IAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAC/B,MAAM,IAAI,aAAa,uBAAuB;EAC5C,WAAW,KAAK;EAChB;CACF,CAAC;CAGH,MAAM,UAAwB,MAAM,UAAU,OAAO,IAAI;CAEzD,IAAI,CAAC,SACH,MAAM,IAAI,aAAa,wBAAwB,EAAE,WAAW,KAAK,MAAM,CAAC;CAG1E,OAAO;AACT;;;;;;AAOA,MAAa,iBAAiB,OAC5B,UACiC;CACjC,OAAO,MAAM,UAAU,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"user.service.mjs","names":[],"sources":["../../../src/services/user.service.ts"],"sourcesContent":["import { UserModel } from '@models/user.model';\nimport { GenericError } from '@utils/errors';\nimport type { UserFilters } from '@utils/filtersAndPagination/getUserFiltersAndPagination';\nimport {\n type FieldsToCheck,\n type UserFields,\n validateUser,\n} from '@utils/validation/validateUser';\nimport type { Types } from 'mongoose';\nimport type { User, UserAPI, UserDocument } from '@/types/user.types';\n\n/**\n * Creates a new user with password in the database and hashes the password.\n * @param user - User object with password not hashed.\n * @returns Created user object.\n */\nexport const createUser = async (\n user: Partial<User>\n): Promise<UserDocument> => {\n const fieldsToCheck: FieldsToCheck[] = ['email'];\n\n const errors = validateUser(user, fieldsToCheck);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userEmail: user.email,\n errors,\n });\n }\n\n const newUser: UserDocument = await UserModel.create(user);\n\n if (!newUser) {\n throw new GenericError('USER_CREATION_FAILED', { userEmail: user.email });\n }\n\n return newUser;\n};\n\n/**\n * Retrieves a user by email.\n * @param email - User's email.\n * @returns User object or null if no user was found.\n */\nexport const getUserByEmail = async (\n email: string\n): Promise<UserDocument | null> => {\n return await UserModel.findOne({ email: String(email) });\n};\n\n/**\n * Retrieves users list by email.\n * @param emails - Users email.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByEmails = async (\n emails: string[]\n): Promise<UserDocument[] | null> => {\n return await UserModel.find({ email: { $in: emails } });\n};\n\n/**\n * Checks if a user exists by email.\n * @param email - User's email.\n * @returns True if the user exists, false otherwise.\n */\nexport const checkUserExists = async (email: string): Promise<boolean> => {\n const user = await UserModel.exists({ email });\n return user !== null;\n};\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUserById = async (\n userId: string | Types.ObjectId\n): Promise<UserDocument | null> => await UserModel.findById(userId);\n\n/**\n * Retrieves a user by ID.\n * @param userId - User's ID.\n * @returns User object or null if no user was found.\n */\nexport const getUsersByIds = async (\n userIds: (string | Types.ObjectId)[]\n): Promise<UserDocument[] | null> =>\n await UserModel.find({ _id: { $in: userIds } });\n\n/**\n * Finds users based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @param sortOptions - Sorting options.\n * @returns List of users matching the filters.\n */\nexport const findUsers = async (\n filters: UserFilters,\n skip: number,\n limit: number,\n sortOptions?: Record<string, 1 | -1>\n): Promise<UserDocument[]> => {\n let query = UserModel.find(filters).skip(skip).limit(limit);\n\n if (sortOptions && Object.keys(sortOptions).length > 0) {\n query = query.sort(sortOptions);\n }\n\n return await query;\n};\n\n/**\n * Counts the total number of users that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of users.\n */\nexport const countUsers = async (filters: UserFilters): Promise<number> => {\n const count = await UserModel.countDocuments(filters);\n\n if (typeof count === 'undefined') {\n throw new GenericError('USER_COUNT_FAILED');\n }\n\n return count;\n};\n\n/**\n * Updates a user's information.\n * @param user - The user object.\n * @param updates - The updates to apply to the user.\n * @returns The updated user.\n */\nexport const updateUserById = async (\n userId: string | Types.ObjectId,\n updates: Partial<UserAPI>\n): Promise<UserDocument> => {\n const { id, ...updatesWithoutId } = updates;\n\n const keyToValidate = Object.keys(updatesWithoutId) as UserFields;\n const errors = validateUser(updatesWithoutId, keyToValidate);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('USER_INVALID_FIELDS', {\n userId,\n errors,\n });\n }\n\n const result = await UserModel.updateOne(\n { _id: userId },\n { $set: updatesWithoutId }\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('USER_UPDATE_FAILED', { userId });\n }\n\n const updatedUser = await UserModel.findById(userId);\n\n if (!updatedUser) {\n throw new GenericError('USER_UPDATED_USER_NOT_FOUND', { userId });\n }\n\n return updatedUser;\n};\n\n/**\n * Deletes a user from the database.\n * @param userId - The user object.\n * @returns\n */\nexport const deleteUser = async (\n userId: string | Types.ObjectId\n): Promise<UserDocument> => {\n await getUserById(userId);\n\n const user = await UserModel.findByIdAndDelete(userId);\n\n if (!user) {\n throw new GenericError('USER_NOT_FOUND', { userId });\n }\n\n return user;\n};\n"],"mappings":";;;;;;;;;;AAgBA,MAAa,aAAa,OACxB,SAC0B;CAG1B,MAAM,SAAS,aAAa,MAAM,CAFM,OAEM,CAAC;CAE/C,IAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAC/B,MAAM,IAAI,aAAa,uBAAuB;EAC5C,WAAW,KAAK;EAChB;CACF,CAAC;CAGH,MAAM,UAAwB,MAAM,UAAU,OAAO,IAAI;CAEzD,IAAI,CAAC,SACH,MAAM,IAAI,aAAa,wBAAwB,EAAE,WAAW,KAAK,MAAM,CAAC;CAG1E,OAAO;AACT;;;;;;AAOA,MAAa,iBAAiB,OAC5B,UACiC;CACjC,OAAO,MAAM,UAAU,QAAQ,EAAE,OAAO,OAAO,KAAK,EAAE,CAAC;AACzD;;;;;;AAOA,MAAa,mBAAmB,OAC9B,WACmC;CACnC,OAAO,MAAM,UAAU,KAAK,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC;AACxD;;;;;;AAOA,MAAa,kBAAkB,OAAO,UAAoC;CAExE,OAAO,MADY,UAAU,OAAO,EAAE,MAAM,CAAC,MAC7B;AAClB;;;;;;AAOA,MAAa,cAAc,OACzB,WACiC,MAAM,UAAU,SAAS,MAAM;;;;;;AAOlE,MAAa,gBAAgB,OAC3B,YAEA,MAAM,UAAU,KAAK,EAAE,KAAK,EAAE,KAAK,QAAQ,EAAE,CAAC;;;;;;;;;AAUhD,MAAa,YAAY,OACvB,SACA,MACA,OACA,gBAC4B;CAC5B,IAAI,QAAQ,UAAU,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;CAE1D,IAAI,eAAe,OAAO,KAAK,WAAW,EAAE,SAAS,GACnD,QAAQ,MAAM,KAAK,WAAW;CAGhC,OAAO,MAAM;AACf;;;;;;AAOA,MAAa,aAAa,OAAO,YAA0C;CACzE,MAAM,QAAQ,MAAM,UAAU,eAAe,OAAO;CAEpD,IAAI,OAAO,UAAU,aACnB,MAAM,IAAI,aAAa,mBAAmB;CAG5C,OAAO;AACT;;;;;;;AAQA,MAAa,iBAAiB,OAC5B,QACA,YAC0B;CAC1B,MAAM,EAAE,IAAI,GAAG,qBAAqB;CAGpC,MAAM,SAAS,aAAa,kBADN,OAAO,KAAK,gBACwB,CAAC;CAE3D,IAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAC/B,MAAM,IAAI,aAAa,uBAAuB;EAC5C;EACA;CACF,CAAC;CAQH,KAAI,MALiB,UAAU,UAC7B,EAAE,KAAK,OAAO,GACd,EAAE,MAAM,iBAAiB,CAC3B,GAEW,iBAAiB,GAC1B,MAAM,IAAI,aAAa,sBAAsB,EAAE,OAAO,CAAC;CAGzD,MAAM,cAAc,MAAM,UAAU,SAAS,MAAM;CAEnD,IAAI,CAAC,aACH,MAAM,IAAI,aAAa,+BAA+B,EAAE,OAAO,CAAC;CAGlE,OAAO;AACT;;;;;;AAOA,MAAa,aAAa,OACxB,WAC0B;CAC1B,MAAM,YAAY,MAAM;CAExB,MAAM,OAAO,MAAM,UAAU,kBAAkB,MAAM;CAErD,IAAI,CAAC,MACH,MAAM,IAAI,aAAa,kBAAkB,EAAE,OAAO,CAAC;CAGrD,OAAO;AACT"}
|