@drodil/backstage-plugin-qeta-backend 3.53.3 → 3.55.0
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/database/DatabaseQetaStore.cjs.js +1 -0
- package/dist/database/DatabaseQetaStore.cjs.js.map +1 -1
- package/dist/database/stores/CollectionsStore.cjs.js +262 -23
- package/dist/database/stores/CollectionsStore.cjs.js.map +1 -1
- package/dist/database/stores/PostsStore.cjs.js +6 -0
- package/dist/database/stores/PostsStore.cjs.js.map +1 -1
- package/dist/service/routes/collections.cjs.js +6 -0
- package/dist/service/routes/collections.cjs.js.map +1 -1
- package/dist/service/types.cjs.js +4 -1
- package/dist/service/types.cjs.js.map +1 -1
- package/dist/service/util.cjs.js +74 -18
- package/dist/service/util.cjs.js.map +1 -1
- package/migrations/20260109_automatic_collections.js +59 -0
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollectionsStore.cjs.js","sources":["../../../src/database/stores/CollectionsStore.ts"],"sourcesContent":["import {\n Collection,\n CollectionsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport {\n CollectionOptions,\n CollectionPostRank,\n Collections,\n} from '../QetaStore';\nimport { Knex } from 'knex';\nimport { compact } from 'lodash';\nimport { BaseStore } from './BaseStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { PostsStore } from './PostsStore';\n\nexport interface RawCollectionEntity {\n id: number;\n title: string;\n description: string;\n created: Date;\n owner: string;\n headerImage: string;\n postsCount: number | string;\n questionsCount: number | string;\n articlesCount: number | string;\n linksCount: number | string;\n followerCount: number | string;\n}\n\nexport class CollectionsStore extends BaseStore {\n constructor(\n protected readonly db: Knex,\n private readonly postsStore: PostsStore,\n private readonly attachmentsStore: AttachmentsStore,\n ) {\n super(db);\n }\n\n async getCollections(\n user_ref: string,\n options: CollectionsQuery,\n opts?: CollectionOptions,\n ): Promise<Collections> {\n const query = this.getCollectionsBaseQuery();\n\n if (options.searchQuery) {\n this.applySearchQuery(\n query,\n ['collections.title', 'collections.description'],\n options.searchQuery,\n );\n }\n\n if (opts?.filters) {\n this.parseFilter(opts.filters, query, this.db, 'collection');\n }\n\n if (options.owner) {\n query.where('collections.owner', '=', options.owner);\n }\n\n const totalQuery = query.clone();\n\n if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n this.db(totalQuery.as('totalQuery')).count('* as CNT').first(),\n ]);\n\n const rows = results[0] as RawCollectionEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n collections: await this.mapCollectionEntities(rows, user_ref, opts),\n total,\n };\n }\n\n async getCollection(\n user_ref: string,\n id: number,\n options?: CollectionOptions,\n ): Promise<Collection | null> {\n const query = this.getCollectionsBaseQuery();\n const rows = await query.where('collections.id', '=', id);\n if (rows.length === 0) {\n return null;\n }\n return (\n await this.mapCollectionEntities(\n [rows[0] as RawCollectionEntity],\n user_ref,\n options,\n )\n )[0];\n }\n\n async createCollection(options: {\n user_ref: string;\n title: string;\n description?: string;\n created: Date;\n images?: number[];\n headerImage?: string;\n opts?: CollectionOptions;\n }): Promise<Collection> {\n const { user_ref, title, description, created, images, headerImage, opts } =\n options as any;\n\n const collections = await this.db\n .insert(\n {\n owner: user_ref,\n title,\n description,\n created,\n headerImage,\n },\n ['id'],\n )\n .into('collections')\n .returning('*');\n\n await this.updateAttachments(\n 'collectionId',\n description ?? '',\n images ?? [],\n collections[0].id,\n headerImage,\n );\n\n return (\n await this.mapCollectionEntities([collections[0]], user_ref, opts)\n )[0];\n }\n\n async updateCollection(options: {\n id: number;\n user_ref: string;\n title: string;\n description?: string;\n images?: number[];\n headerImage?: string;\n opts?: CollectionOptions;\n }): Promise<Collection | null> {\n const { id, user_ref, title, description, images, headerImage, opts } =\n options;\n\n const rows = await this.db('collections')\n .where('id', '=', id)\n .update({\n title,\n description,\n headerImage,\n })\n .returning('*');\n\n if (!rows || rows.length === 0) {\n return null;\n }\n\n await this.updateAttachments(\n 'collectionId',\n description ?? '',\n images ?? [],\n id,\n headerImage,\n );\n\n return (await this.mapCollectionEntities([rows[0]], user_ref, opts))[0];\n }\n\n async deleteCollection(id: number): Promise<boolean> {\n const rows = await this.db('collections').where('id', '=', id).delete();\n return rows > 0;\n }\n\n async getUserCollections(\n user_ref: string,\n options?: CollectionOptions,\n ): Promise<{ collections: Collection[]; count: number }> {\n const results = await this.getCollections(user_ref, options || {});\n return { collections: results.collections, count: results.total };\n }\n\n async getPostRank(\n collectionId: number,\n postId: number,\n ): Promise<number | null> {\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('postId', postId)\n .first();\n\n if (!post) {\n return null;\n }\n\n return post.rank;\n }\n\n async getTopRankedPostId(\n collectionId: number,\n ): Promise<CollectionPostRank | null> {\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .orderBy('rank', 'asc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async getBottomRankedPostId(\n collectionId: number,\n ): Promise<CollectionPostRank | null> {\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .orderBy('rank', 'desc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async getNextRankedPostId(\n collectionId: number,\n postId: number,\n ): Promise<CollectionPostRank | null> {\n const currentPostRank = await this.getPostRank(collectionId, postId);\n if (currentPostRank === null) {\n return null;\n }\n\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('rank', '>', currentPostRank)\n .orderBy('rank', 'asc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async getPreviousRankedPostId(\n collectionId: number,\n postId: number,\n ): Promise<CollectionPostRank | null> {\n const currentPostRank = await this.getPostRank(collectionId, postId);\n if (currentPostRank === null) {\n return null;\n }\n\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('rank', '<', currentPostRank)\n .orderBy('rank', 'desc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async updatePostRank(\n collectionId: number,\n postId: number,\n rank: number,\n ): Promise<void> {\n await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('postId', postId)\n .update({ rank });\n }\n\n async addPostToCollection(\n user_ref: string,\n id: number,\n postId: number,\n options?: CollectionOptions,\n ): Promise<Collection | null> {\n await this.db\n .insert({\n collectionId: id,\n postId,\n })\n .into('collection_posts');\n await this.db('collections').where('id', id).increment('postsCount', 1);\n return this.getCollection(user_ref, id, options);\n }\n\n async removePostFromCollection(\n user_ref: string,\n id: number,\n postId: number,\n options?: CollectionOptions,\n ): Promise<Collection | null> {\n const rows = await this.db('collection_posts')\n .where('collectionId', id)\n .where('postId', postId)\n .delete();\n if (rows > 0) {\n await this.db('collections').where('id', id).decrement('postsCount', 1);\n }\n return this.getCollection(user_ref, id, options);\n }\n\n async getUsersForCollection(collectionId: number): Promise<string[]> {\n const users = await this.db('user_collections')\n .where('collectionId', collectionId)\n .select('userRef');\n return users.map(user => user.userRef);\n }\n\n async followCollection(\n user_ref: string,\n collectionId: number,\n ): Promise<boolean> {\n await this.db\n .insert({\n userRef: user_ref,\n collectionId,\n })\n .into('user_collections');\n return true;\n }\n\n async unfollowCollection(\n user_ref: string,\n collectionId: number,\n ): Promise<boolean> {\n await this.db('user_collections')\n .where('userRef', user_ref)\n .where('collectionId', collectionId)\n .delete();\n return true;\n }\n\n async getFollowerCounts(ids: number[]): Promise<Map<number, number>> {\n if (ids.length === 0) {\n return new Map();\n }\n const followers = await this.db('user_collections')\n .select('collectionId')\n .count('* as count')\n .whereIn('collectionId', ids)\n .groupBy('collectionId');\n\n const result = new Map<number, number>();\n followers.forEach((f: any) => {\n result.set(f.collectionId, this.mapToInteger(f.count));\n });\n return result;\n }\n\n private async mapCollectionEntities(\n rows: RawCollectionEntity[],\n user_ref: string,\n options?: CollectionOptions,\n ): Promise<Collection[]> {\n if (rows.length === 0) {\n return [];\n }\n\n const collectionIds = rows.map(r => r.id);\n const {\n postFilters,\n includePosts = true,\n includeExperts = true,\n } = options ?? {};\n\n const [posts, attachments, followers, experts] = await Promise.all([\n includePosts && this.postsStore\n ? this.postsStore.getPosts(\n user_ref,\n { includeEntities: true },\n postFilters,\n {\n tagsFilter: options?.tagFilters,\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeVotes: false,\n includeTotal: false,\n includeExperts: includeExperts ?? false,\n includeCollections: true,\n collectionIds: collectionIds,\n },\n )\n : { posts: [] },\n this.attachmentsStore.getAttachments(collectionIds, 'collectionId'),\n this.getFollowerCounts(collectionIds),\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('tags', 'tag_experts.tagId', 'tags.id')\n .leftJoin('post_tags', 'post_tags.tagId', 'tags.id')\n .leftJoin(\n 'collection_posts',\n 'collection_posts.postId',\n 'post_tags.postId',\n )\n .whereIn('collection_posts.collectionId', collectionIds)\n .select('collection_posts.collectionId', 'tag_experts.entityRef')\n : undefined,\n ]);\n\n const postsMap = new Map<number, any[]>();\n posts.posts?.forEach((p: any) => {\n if (p.collectionIds && Array.isArray(p.collectionIds)) {\n p.collectionIds.forEach((collectionId: number) => {\n const ps = postsMap.get(collectionId) || [];\n ps.push(p);\n postsMap.set(collectionId, ps);\n });\n }\n });\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const followersMap = followers ?? new Map<number, number>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.collectionId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.collectionId, ps);\n });\n\n return rows.map(val => {\n const collectionPosts = postsMap.get(val.id) || [];\n const entities = compact([\n ...new Set(collectionPosts.map((p: any) => p.entities).flat()),\n ]);\n const tags = compact([\n ...new Set(collectionPosts.map((p: any) => p.tags).flat()),\n ]);\n\n return {\n id: val.id,\n title: val.title,\n owner: val.owner,\n description: val.description,\n created: val.created as Date,\n posts: collectionPosts,\n headerImage: val.headerImage,\n postsCount: this.mapToInteger(val.postsCount),\n questionsCount: this.mapToInteger(val.questionsCount),\n articlesCount: this.mapToInteger(val.articlesCount),\n linksCount: this.mapToInteger(val.linksCount),\n entities: entities as string[],\n tags: tags as string[],\n images: attachmentsMap.get(val.id) || [],\n followers: followersMap.get(val.id) || 0,\n experts: expertsMap.get(val.id),\n };\n });\n }\n\n private getCollectionsBaseQuery() {\n const questionsCount = this.db('collection_posts')\n .leftJoin('posts', 'collection_posts.postId', 'posts.id')\n .where('collection_posts.collectionId', this.db.ref('collections.id'))\n .where('posts.type', 'question')\n .count('*')\n .as('questionsCount');\n\n const articlesCount = this.db('collection_posts')\n .leftJoin('posts', 'collection_posts.postId', 'posts.id')\n .where('collection_posts.collectionId', this.db.ref('collections.id'))\n .where('posts.type', 'article')\n .count('*')\n .as('articlesCount');\n\n const linksCount = this.db('collection_posts')\n .leftJoin('posts', 'collection_posts.postId', 'posts.id')\n .where('collection_posts.collectionId', this.db.ref('collections.id'))\n .where('posts.type', 'link')\n .count('*')\n .as('linksCount');\n\n const followerCount = this.db('user_collections')\n .where('user_collections.collectionId', this.db.ref('collections.id'))\n .count('*')\n .as('followerCount');\n\n return this.db<RawCollectionEntity>('collections')\n .select(\n 'collections.*',\n questionsCount,\n articlesCount,\n linksCount,\n followerCount,\n )\n .groupBy('collections.id');\n }\n}\n"],"names":["BaseStore","compact"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CollectionsStore.cjs.js","sources":["../../../src/database/stores/CollectionsStore.ts"],"sourcesContent":["import {\n filterTags,\n Collection,\n CollectionsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport {\n CollectionOptions,\n CollectionPostRank,\n Collections,\n} from '../QetaStore';\nimport { Knex } from 'knex';\nimport { compact } from 'lodash';\nimport { BaseStore } from './BaseStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { PostsStore } from './PostsStore';\nimport { TAGS } from '../../tagDb';\nimport { TagDatabase } from '@drodil/backstage-plugin-qeta-node';\n\nexport interface RawCollectionEntity {\n id: number;\n title: string;\n description: string;\n created: Date;\n owner: string;\n headerImage: string;\n postsCount: number | string;\n questionsCount: number | string;\n articlesCount: number | string;\n linksCount: number | string;\n followerCount: number | string;\n}\n\nexport class CollectionsStore extends BaseStore {\n constructor(\n protected readonly db: Knex,\n private readonly postsStore: PostsStore,\n private readonly attachmentsStore: AttachmentsStore,\n private readonly tagDatabase?: TagDatabase,\n ) {\n super(db);\n }\n\n async getCollections(\n user_ref: string,\n options: CollectionsQuery,\n opts?: CollectionOptions,\n ): Promise<Collections> {\n const query = this.getCollectionsBaseQuery();\n\n if (options.searchQuery) {\n this.applySearchQuery(\n query,\n ['collections.title', 'collections.description'],\n options.searchQuery,\n );\n }\n\n if (opts?.filters) {\n this.parseFilter(opts.filters, query, this.db, 'collection');\n }\n\n if (options.owner) {\n query.where('collections.owner', '=', options.owner);\n }\n\n const totalQuery = query.clone();\n\n if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n this.db(totalQuery.as('totalQuery')).count('* as CNT').first(),\n ]);\n\n const rows = results[0] as RawCollectionEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n collections: await this.mapCollectionEntities(rows, user_ref, opts),\n total,\n };\n }\n\n async getCollection(\n user_ref: string,\n id: number,\n options?: CollectionOptions,\n ): Promise<Collection | null> {\n const query = this.getCollectionsBaseQuery();\n const rows = await query.where('collections.id', '=', id);\n if (rows.length === 0) {\n return null;\n }\n return (\n await this.mapCollectionEntities(\n [rows[0] as RawCollectionEntity],\n user_ref,\n options,\n )\n )[0];\n }\n\n async createCollection(options: {\n user_ref: string;\n title: string;\n description?: string;\n created: Date;\n images?: number[];\n headerImage?: string;\n opts?: CollectionOptions;\n }): Promise<Collection> {\n const {\n user_ref,\n title,\n description,\n created,\n images,\n headerImage,\n tags,\n entities,\n users,\n opts,\n } = options as any;\n\n const collections = await this.db\n .insert(\n {\n owner: user_ref,\n title,\n description,\n created,\n headerImage,\n },\n ['id'],\n )\n .into('collections')\n .returning('*');\n\n await Promise.all([\n this.updateAttachments(\n 'collectionId',\n description ?? '',\n images ?? [],\n collections[0].id,\n headerImage,\n ),\n this.addCollectionTags(collections[0].id, tags),\n this.addCollectionEntities(collections[0].id, entities),\n this.addCollectionUsers(collections[0].id, users),\n ]);\n\n await this.syncCollectionToPosts(collections[0].id);\n\n return (\n await this.mapCollectionEntities([collections[0]], user_ref, opts)\n )[0];\n }\n\n async updateCollection(options: {\n id: number;\n user_ref: string;\n title: string;\n description?: string;\n images?: number[];\n headerImage?: string;\n opts?: CollectionOptions;\n }): Promise<Collection | null> {\n const {\n id,\n user_ref,\n title,\n description,\n images,\n headerImage,\n tags,\n entities,\n users,\n opts,\n } = options as any;\n\n const rows = await this.db('collections')\n .where('id', '=', id)\n .update({\n title,\n description,\n headerImage,\n })\n .returning('*');\n\n if (!rows || rows.length === 0) {\n return null;\n }\n\n await Promise.all([\n this.updateAttachments(\n 'collectionId',\n description ?? '',\n images ?? [],\n id,\n headerImage,\n ),\n this.addCollectionTags(id, tags, true),\n this.addCollectionEntities(id, entities, true),\n this.addCollectionUsers(id, users, true),\n ]);\n\n await this.syncCollectionToPosts(id);\n\n return (await this.mapCollectionEntities([rows[0]], user_ref, opts))[0];\n }\n\n async deleteCollection(id: number): Promise<boolean> {\n const rows = await this.db('collections').where('id', '=', id).delete();\n return rows > 0;\n }\n\n async getUserCollections(\n user_ref: string,\n options?: CollectionOptions,\n ): Promise<{ collections: Collection[]; count: number }> {\n const results = await this.getCollections(user_ref, options || {});\n return { collections: results.collections, count: results.total };\n }\n\n async getPostRank(\n collectionId: number,\n postId: number,\n ): Promise<number | null> {\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('postId', postId)\n .first();\n\n if (!post) {\n return null;\n }\n\n return post.rank;\n }\n\n async getTopRankedPostId(\n collectionId: number,\n ): Promise<CollectionPostRank | null> {\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .orderBy('rank', 'asc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async getBottomRankedPostId(\n collectionId: number,\n ): Promise<CollectionPostRank | null> {\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .orderBy('rank', 'desc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async getNextRankedPostId(\n collectionId: number,\n postId: number,\n ): Promise<CollectionPostRank | null> {\n const currentPostRank = await this.getPostRank(collectionId, postId);\n if (currentPostRank === null) {\n return null;\n }\n\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('rank', '>', currentPostRank)\n .orderBy('rank', 'asc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async getPreviousRankedPostId(\n collectionId: number,\n postId: number,\n ): Promise<CollectionPostRank | null> {\n const currentPostRank = await this.getPostRank(collectionId, postId);\n if (currentPostRank === null) {\n return null;\n }\n\n const post = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('rank', '<', currentPostRank)\n .orderBy('rank', 'desc')\n .first();\n\n return post ? { postId: post.postId, rank: post.rank } : null;\n }\n\n async updatePostRank(\n collectionId: number,\n postId: number,\n rank: number,\n ): Promise<void> {\n await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('postId', postId)\n .update({ rank });\n }\n\n async addPostToCollection(\n user_ref: string,\n id: number,\n postId: number,\n options?: CollectionOptions,\n ): Promise<Collection | null> {\n await this.db\n .insert({\n collectionId: id,\n postId,\n })\n .into('collection_posts');\n await this.db('collections').where('id', id).increment('postsCount', 1);\n return this.getCollection(user_ref, id, options);\n }\n\n async removePostFromCollection(\n user_ref: string,\n id: number,\n postId: number,\n options?: CollectionOptions,\n ): Promise<Collection | null> {\n const rows = await this.db('collection_posts')\n .where('collectionId', id)\n .where('postId', postId)\n .delete();\n if (rows > 0) {\n await this.db('collections').where('id', id).decrement('postsCount', 1);\n }\n return this.getCollection(user_ref, id, options);\n }\n\n async getUsersForCollection(collectionId: number): Promise<string[]> {\n const users = await this.db('user_collections')\n .where('collectionId', collectionId)\n .select('userRef');\n return users.map(user => user.userRef);\n }\n\n async syncCollectionToPosts(collectionId: number) {\n const tags = await this.getCollectionTags([collectionId]);\n const entities = await this.getCollectionEntities([collectionId]);\n const users = await this.getCollectionUsers([collectionId]);\n\n const collectionTags = tags.get(collectionId) || [];\n const collectionEntities = entities.get(collectionId) || [];\n const collectionUsers = users.get(collectionId) || [];\n\n if (\n collectionTags.length === 0 &&\n collectionEntities.length === 0 &&\n collectionUsers.length === 0\n ) {\n await this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('automatic', true)\n .delete();\n return;\n }\n\n const posts = await this.db('posts')\n .leftJoin('post_tags', 'posts.id', 'post_tags.postId')\n .leftJoin('tags', 'post_tags.tagId', 'tags.id')\n .leftJoin('post_entities', 'posts.id', 'post_entities.postId')\n .leftJoin('entities', 'post_entities.entityId', 'entities.id')\n .where(builder => {\n if (collectionTags.length > 0) {\n builder.orWhereIn('tags.tag', collectionTags);\n }\n if (collectionEntities.length > 0) {\n builder.orWhereIn('entities.entity_ref', collectionEntities);\n }\n if (collectionUsers.length > 0) {\n builder.orWhereIn('posts.author', collectionUsers);\n }\n })\n .select('posts.id')\n .distinct();\n\n const postIds = posts.map(p => p.id);\n if (postIds.length > 0) {\n await Promise.all(\n postIds.map(async postId => {\n await this.db\n .insert({\n collectionId,\n postId,\n automatic: true,\n })\n .into('collection_posts')\n .onConflict(['collectionId', 'postId'])\n .ignore();\n }),\n );\n }\n\n const deleteQuery = this.db('collection_posts')\n .where('collectionId', collectionId)\n .where('automatic', true);\n\n if (postIds.length > 0) {\n deleteQuery.whereNotIn('postId', postIds);\n }\n\n await deleteQuery.delete();\n const count = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .count('* as CNT')\n .first();\n await this.db('collections')\n .where('id', collectionId)\n .update('postsCount', this.mapToInteger((count as any)?.CNT));\n }\n\n async syncPostToCollections(postId: number) {\n const post = await this.postsStore.getPost('', postId);\n\n if (!post) {\n return;\n }\n\n const postTags = post.tags || [];\n const postEntities = post.entities || [];\n const postAuthor = post.author;\n\n const collections = await this.db('collections')\n .leftJoin(\n 'collection_tags',\n 'collections.id',\n 'collection_tags.collectionId',\n )\n .leftJoin('tags', 'collection_tags.tagId', 'tags.id')\n .leftJoin(\n 'collection_entities',\n 'collections.id',\n 'collection_entities.collectionId',\n )\n .leftJoin('entities', 'collection_entities.entityId', 'entities.id')\n .leftJoin(\n 'collection_users',\n 'collections.id',\n 'collection_users.collectionId',\n )\n .where(builder => {\n if (postTags.length > 0) {\n builder.orWhereIn('tags.tag', postTags);\n }\n if (postEntities.length > 0) {\n builder.orWhereIn('entities.entity_ref', postEntities);\n }\n if (postAuthor) {\n builder.orWhere('collection_users.userRef', postAuthor);\n }\n })\n .select('collections.id')\n .distinct();\n\n const collectionIds = collections.map(c => c.id);\n\n if (collectionIds.length > 0) {\n await Promise.all(\n collectionIds.map(async collectionId => {\n await this.db\n .insert({\n collectionId,\n postId,\n automatic: true,\n })\n .into('collection_posts')\n .onConflict(['collectionId', 'postId'])\n .ignore();\n }),\n );\n }\n\n const deleteQuery = this.db('collection_posts')\n .where('postId', postId)\n .where('automatic', true);\n\n if (collectionIds.length > 0) {\n deleteQuery.whereNotIn('collectionId', collectionIds);\n }\n\n await deleteQuery.delete();\n\n if (collectionIds.length > 0) {\n await Promise.all(\n collectionIds.map(async collectionId => {\n const count = await this.db('collection_posts')\n .where('collectionId', collectionId)\n .count('* as CNT')\n .first();\n await this.db('collections')\n .where('id', collectionId)\n .update('postsCount', this.mapToInteger((count as any)?.CNT));\n }),\n );\n }\n }\n\n async followCollection(\n user_ref: string,\n collectionId: number,\n ): Promise<boolean> {\n await this.db\n .insert({\n userRef: user_ref,\n collectionId,\n })\n .into('user_collections');\n return true;\n }\n\n async unfollowCollection(\n user_ref: string,\n collectionId: number,\n ): Promise<boolean> {\n await this.db('user_collections')\n .where('userRef', user_ref)\n .where('collectionId', collectionId)\n .delete();\n return true;\n }\n\n async getFollowerCounts(ids: number[]): Promise<Map<number, number>> {\n if (ids.length === 0) {\n return new Map();\n }\n const followers = await this.db('user_collections')\n .select('collectionId')\n .count('* as count')\n .whereIn('collectionId', ids)\n .groupBy('collectionId');\n\n const result = new Map<number, number>();\n followers.forEach((f: any) => {\n result.set(f.collectionId, this.mapToInteger(f.count));\n });\n return result;\n }\n\n private async mapCollectionEntities(\n rows: RawCollectionEntity[],\n user_ref: string,\n options?: CollectionOptions,\n ): Promise<Collection[]> {\n if (rows.length === 0) {\n return [];\n }\n\n const collectionIds = rows.map(r => r.id);\n const {\n postFilters,\n includePosts = true,\n includeExperts = true,\n } = options ?? {};\n\n const [posts, attachments, followers, experts, tags, entities, users] =\n await Promise.all([\n includePosts && this.postsStore\n ? this.postsStore.getPosts(\n user_ref,\n { includeEntities: true },\n postFilters,\n {\n tagsFilter: options?.tagFilters,\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeVotes: false,\n includeTotal: false,\n includeExperts: includeExperts ?? false,\n includeHealth: false,\n includeTags: true,\n includeCollections: true,\n collectionIds: collectionIds,\n },\n )\n : { posts: [] },\n this.attachmentsStore.getAttachments(collectionIds, 'collectionId'),\n this.getFollowerCounts(collectionIds),\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('tags', 'tag_experts.tagId', 'tags.id')\n .leftJoin('post_tags', 'post_tags.tagId', 'tags.id')\n .leftJoin(\n 'collection_posts',\n 'collection_posts.postId',\n 'post_tags.postId',\n )\n .whereIn('collection_posts.collectionId', collectionIds)\n .select('collection_posts.collectionId', 'tag_experts.entityRef')\n : undefined,\n this.getCollectionTags(collectionIds),\n this.getCollectionEntities(collectionIds),\n this.getCollectionUsers(collectionIds),\n ]);\n\n const postsMap = new Map<number, any[]>();\n posts.posts?.forEach((p: any) => {\n if (p.collectionIds && Array.isArray(p.collectionIds)) {\n p.collectionIds.forEach((collectionId: number) => {\n const ps = postsMap.get(collectionId) || [];\n ps.push(p);\n postsMap.set(collectionId, ps);\n });\n }\n });\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const followersMap = followers ?? new Map<number, number>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.collectionId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.collectionId, ps);\n });\n\n return rows.map(val => {\n const collectionPosts = postsMap.get(val.id) || [];\n const postEntities = compact([\n ...new Set(collectionPosts.map((p: any) => p.entities).flat()),\n ]);\n const postTags = compact([\n ...new Set(collectionPosts.map((p: any) => p.tags).flat()),\n ]);\n\n return {\n id: val.id,\n title: val.title,\n owner: val.owner,\n description: val.description,\n created: val.created as Date,\n posts: collectionPosts,\n headerImage: val.headerImage,\n postsCount: this.mapToInteger(val.postsCount),\n questionsCount: this.mapToInteger(val.questionsCount),\n articlesCount: this.mapToInteger(val.articlesCount),\n linksCount: this.mapToInteger(val.linksCount),\n entities: entities.get(val.id) || [],\n tags: tags.get(val.id) || [],\n users: users.get(val.id) || [],\n postEntities: postEntities as string[],\n postTags: postTags as string[],\n images: attachmentsMap.get(val.id) || [],\n followers: followersMap.get(val.id) || 0,\n experts: expertsMap.get(val.id),\n };\n });\n }\n\n async getCollectionTags(ids: number[]): Promise<Map<number, string[]>> {\n const rows = await this.db('collection_tags')\n .leftJoin('tags', 'collection_tags.tagId', 'tags.id')\n .whereIn('collection_tags.collectionId', ids)\n .select('collection_tags.collectionId', 'tags.tag');\n\n const result = new Map<number, string[]>();\n rows.forEach(row => {\n const tags = result.get(row.collectionId) || [];\n tags.push(row.tag);\n result.set(row.collectionId, tags);\n });\n return result;\n }\n\n async getCollectionEntities(ids: number[]): Promise<Map<number, string[]>> {\n const rows = await this.db('collection_entities')\n .leftJoin('entities', 'collection_entities.entityId', 'entities.id')\n .whereIn('collection_entities.collectionId', ids)\n .select('collection_entities.collectionId', 'entities.entity_ref');\n\n const result = new Map<number, string[]>();\n rows.forEach(row => {\n const entities = result.get(row.collectionId) || [];\n entities.push(row.entity_ref);\n result.set(row.collectionId, entities);\n });\n return result;\n }\n\n async getCollectionUsers(ids: number[]): Promise<Map<number, string[]>> {\n const rows = await this.db('collection_users')\n .whereIn('collectionId', ids)\n .select('collectionId', 'userRef');\n\n const result = new Map<number, string[]>();\n rows.forEach(row => {\n const users = result.get(row.collectionId) || [];\n users.push(row.userRef);\n result.set(row.collectionId, users);\n });\n return result;\n }\n\n private getCollectionsBaseQuery() {\n const questionsCount = this.db('collection_posts')\n .leftJoin('posts', 'collection_posts.postId', 'posts.id')\n .where('collection_posts.collectionId', this.db.ref('collections.id'))\n .where('posts.type', 'question')\n .count('*')\n .as('questionsCount');\n\n const articlesCount = this.db('collection_posts')\n .leftJoin('posts', 'collection_posts.postId', 'posts.id')\n .where('collection_posts.collectionId', this.db.ref('collections.id'))\n .where('posts.type', 'article')\n .count('*')\n .as('articlesCount');\n\n const linksCount = this.db('collection_posts')\n .leftJoin('posts', 'collection_posts.postId', 'posts.id')\n .where('collection_posts.collectionId', this.db.ref('collections.id'))\n .where('posts.type', 'link')\n .count('*')\n .as('linksCount');\n\n const followerCount = this.db('user_collections')\n .where('user_collections.collectionId', this.db.ref('collections.id'))\n .count('*')\n .as('followerCount');\n\n return this.db<RawCollectionEntity>('collections')\n .select(\n 'collections.*',\n questionsCount,\n articlesCount,\n linksCount,\n followerCount,\n )\n .groupBy('collections.id');\n }\n\n private async addCollectionTags(\n id: number,\n tagsInput?: string[],\n removeOld?: boolean,\n ) {\n const tags = filterTags(tagsInput);\n if (removeOld) {\n await this.db('collection_tags').where('collectionId', '=', id).delete();\n }\n\n if (!tags || tags.length === 0) {\n return;\n }\n\n const existingTags = await this.db('tags')\n .whereIn('tag', tags)\n .returning('id')\n .select();\n const newTags = tags.filter(t => !existingTags.some(e => e.tag === t));\n const allTags: Record<string, string> = {\n ...TAGS,\n ...(await this.tagDatabase?.getTags()),\n };\n\n const tagIds = (\n await Promise.all(\n [...new Set(newTags)].map(async tag => {\n const trimmed = tag.trim();\n const description = trimmed in allTags ? allTags[trimmed] : undefined;\n\n return this.db\n .insert({ tag: trimmed, description })\n .into('tags')\n .returning('id')\n .onConflict('tag')\n .ignore();\n }),\n )\n )\n .flat()\n .map(tag => tag.id)\n .concat(existingTags.map(t => t.id));\n\n await Promise.all(\n tagIds.map(async tagId => {\n await this.db\n .insert({ collectionId: id, tagId })\n .into('collection_tags')\n .onConflict()\n .ignore();\n }),\n );\n }\n\n private async addCollectionEntities(\n id: number,\n entitiesInput?: string[],\n removeOld?: boolean,\n ) {\n if (removeOld) {\n await this.db('collection_entities')\n .where('collectionId', '=', id)\n .delete();\n }\n\n const regex = /\\w+:\\w+\\/\\w+/;\n const entities =\n entitiesInput\n ?.filter(t => regex.test(t))\n .map(t => t.toLowerCase())\n .filter(t => t.length > 0) ?? [];\n\n if (!entities || entities.length === 0) {\n return;\n }\n\n const existingEntities = await this.db('entities')\n .whereIn('entity_ref', entities)\n .returning('id')\n .select();\n const newEntities = entities.filter(\n t => !existingEntities.some(e => e.entity_ref === t),\n );\n\n const entityIds = (\n await Promise.all(\n [...new Set(newEntities)].map(async entityRef =>\n this.db\n .insert({ entity_ref: entityRef })\n .into('entities')\n .returning('id')\n .onConflict('entity_ref')\n .ignore(),\n ),\n )\n )\n .flat()\n .map(entity => entity.id)\n .concat(existingEntities.map(c => c.id));\n\n await Promise.all(\n entityIds.map(async entityId => {\n await this.db\n .insert({ collectionId: id, entityId })\n .into('collection_entities')\n .onConflict()\n .ignore();\n }),\n );\n }\n\n private async addCollectionUsers(\n id: number,\n usersInput?: string[],\n removeOld?: boolean,\n ) {\n if (removeOld) {\n await this.db('collection_users').where('collectionId', '=', id).delete();\n }\n\n const users = [...new Set(usersInput?.filter(u => u.length > 0) ?? [])];\n\n if (users.length === 0) {\n return;\n }\n\n await Promise.all(\n users.map(async userRef => {\n await this.db\n .insert({ collectionId: id, userRef })\n .into('collection_users');\n }),\n );\n }\n}\n"],"names":["BaseStore","compact","filterTags","TAGS"],"mappings":";;;;;;;AAgCO,MAAM,yBAAyBA,mBAAU,CAAA;AAAA,EAC9C,WACqB,CAAA,EAAA,EACF,UACA,EAAA,gBAAA,EACA,WACjB,EAAA;AACA,IAAA,KAAA,CAAM,EAAE,CAAA;AALW,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AACF,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,gBAAA,GAAA,gBAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA;AAGnB,EAEA,MAAM,cAAA,CACJ,QACA,EAAA,OAAA,EACA,IACsB,EAAA;AACtB,IAAM,MAAA,KAAA,GAAQ,KAAK,uBAAwB,EAAA;AAE3C,IAAA,IAAI,QAAQ,WAAa,EAAA;AACvB,MAAK,IAAA,CAAA,gBAAA;AAAA,QACH,KAAA;AAAA,QACA,CAAC,qBAAqB,yBAAyB,CAAA;AAAA,QAC/C,OAAQ,CAAA;AAAA,OACV;AAAA;AAGF,IAAA,IAAI,MAAM,OAAS,EAAA;AACjB,MAAA,IAAA,CAAK,YAAY,IAAK,CAAA,OAAA,EAAS,KAAO,EAAA,IAAA,CAAK,IAAI,YAAY,CAAA;AAAA;AAG7D,IAAA,IAAI,QAAQ,KAAO,EAAA;AACjB,MAAA,KAAA,CAAM,KAAM,CAAA,mBAAA,EAAqB,GAAK,EAAA,OAAA,CAAQ,KAAK,CAAA;AAAA;AAGrD,IAAM,MAAA,UAAA,GAAa,MAAM,KAAM,EAAA;AAE/B,IAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,MAAA,KAAA,CAAM,QAAQ,OAAQ,CAAA,OAAA,EAAS,QAAQ,KAAQ,GAAA,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAAA;AAGvE,IAAA,IAAI,QAAQ,KAAO,EAAA;AACjB,MAAM,KAAA,CAAA,KAAA,CAAM,QAAQ,KAAK,CAAA;AAAA;AAG3B,IAAA,IAAI,QAAQ,MAAQ,EAAA;AAClB,MAAM,KAAA,CAAA,MAAA,CAAO,QAAQ,MAAM,CAAA;AAAA;AAG7B,IAAM,MAAA,OAAA,GAAU,MAAM,OAAA,CAAQ,GAAI,CAAA;AAAA,MAChC,KAAA;AAAA,MACA,IAAA,CAAK,EAAG,CAAA,UAAA,CAAW,EAAG,CAAA,YAAY,CAAC,CAAE,CAAA,KAAA,CAAM,UAAU,CAAA,CAAE,KAAM;AAAA,KAC9D,CAAA;AAED,IAAM,MAAA,IAAA,GAAO,QAAQ,CAAC,CAAA;AACtB,IAAA,MAAM,QAAQ,IAAK,CAAA,YAAA,CAAc,OAAQ,CAAA,CAAC,GAAW,GAAG,CAAA;AAExD,IAAO,OAAA;AAAA,MACL,aAAa,MAAM,IAAA,CAAK,qBAAsB,CAAA,IAAA,EAAM,UAAU,IAAI,CAAA;AAAA,MAClE;AAAA,KACF;AAAA;AACF,EAEA,MAAM,aAAA,CACJ,QACA,EAAA,EAAA,EACA,OAC4B,EAAA;AAC5B,IAAM,MAAA,KAAA,GAAQ,KAAK,uBAAwB,EAAA;AAC3C,IAAA,MAAM,OAAO,MAAM,KAAA,CAAM,KAAM,CAAA,gBAAA,EAAkB,KAAK,EAAE,CAAA;AACxD,IAAI,IAAA,IAAA,CAAK,WAAW,CAAG,EAAA;AACrB,MAAO,OAAA,IAAA;AAAA;AAET,IAAA,OAAA,CACE,MAAM,IAAK,CAAA,qBAAA;AAAA,MACT,CAAC,IAAK,CAAA,CAAC,CAAwB,CAAA;AAAA,MAC/B,QAAA;AAAA,MACA;AAAA,OAEF,CAAC,CAAA;AAAA;AACL,EAEA,MAAM,iBAAiB,OAQC,EAAA;AACtB,IAAM,MAAA;AAAA,MACJ,QAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAA;AAAA,MACA,WAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACE,GAAA,OAAA;AAEJ,IAAM,MAAA,WAAA,GAAc,MAAM,IAAA,CAAK,EAC5B,CAAA,MAAA;AAAA,MACC;AAAA,QACE,KAAO,EAAA,QAAA;AAAA,QACP,KAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,CAAC,IAAI;AAAA,KAEN,CAAA,IAAA,CAAK,aAAa,CAAA,CAClB,UAAU,GAAG,CAAA;AAEhB,IAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,MAChB,IAAK,CAAA,iBAAA;AAAA,QACH,cAAA;AAAA,QACA,WAAe,IAAA,EAAA;AAAA,QACf,UAAU,EAAC;AAAA,QACX,WAAA,CAAY,CAAC,CAAE,CAAA,EAAA;AAAA,QACf;AAAA,OACF;AAAA,MACA,KAAK,iBAAkB,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,IAAI,IAAI,CAAA;AAAA,MAC9C,KAAK,qBAAsB,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,IAAI,QAAQ,CAAA;AAAA,MACtD,KAAK,kBAAmB,CAAA,WAAA,CAAY,CAAC,CAAA,CAAE,IAAI,KAAK;AAAA,KACjD,CAAA;AAED,IAAA,MAAM,IAAK,CAAA,qBAAA,CAAsB,WAAY,CAAA,CAAC,EAAE,EAAE,CAAA;AAElD,IACE,OAAA,CAAA,MAAM,IAAK,CAAA,qBAAA,CAAsB,CAAC,WAAA,CAAY,CAAC,CAAC,CAAG,EAAA,QAAA,EAAU,IAAI,CAAA,EACjE,CAAC,CAAA;AAAA;AACL,EAEA,MAAM,iBAAiB,OAQQ,EAAA;AAC7B,IAAM,MAAA;AAAA,MACJ,EAAA;AAAA,MACA,QAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,WAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACE,GAAA,OAAA;AAEJ,IAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,EAAG,CAAA,aAAa,CACrC,CAAA,KAAA,CAAM,IAAM,EAAA,GAAA,EAAK,EAAE,CAAA,CACnB,MAAO,CAAA;AAAA,MACN,KAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACD,CACA,CAAA,SAAA,CAAU,GAAG,CAAA;AAEhB,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,KAAW,CAAG,EAAA;AAC9B,MAAO,OAAA,IAAA;AAAA;AAGT,IAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,MAChB,IAAK,CAAA,iBAAA;AAAA,QACH,cAAA;AAAA,QACA,WAAe,IAAA,EAAA;AAAA,QACf,UAAU,EAAC;AAAA,QACX,EAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,IAAK,CAAA,iBAAA,CAAkB,EAAI,EAAA,IAAA,EAAM,IAAI,CAAA;AAAA,MACrC,IAAK,CAAA,qBAAA,CAAsB,EAAI,EAAA,QAAA,EAAU,IAAI,CAAA;AAAA,MAC7C,IAAK,CAAA,kBAAA,CAAmB,EAAI,EAAA,KAAA,EAAO,IAAI;AAAA,KACxC,CAAA;AAED,IAAM,MAAA,IAAA,CAAK,sBAAsB,EAAE,CAAA;AAEnC,IAAQ,OAAA,CAAA,MAAM,IAAK,CAAA,qBAAA,CAAsB,CAAC,IAAA,CAAK,CAAC,CAAC,CAAG,EAAA,QAAA,EAAU,IAAI,CAAA,EAAG,CAAC,CAAA;AAAA;AACxE,EAEA,MAAM,iBAAiB,EAA8B,EAAA;AACnD,IAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,EAAG,CAAA,aAAa,CAAE,CAAA,KAAA,CAAM,IAAM,EAAA,GAAA,EAAK,EAAE,CAAA,CAAE,MAAO,EAAA;AACtE,IAAA,OAAO,IAAO,GAAA,CAAA;AAAA;AAChB,EAEA,MAAM,kBACJ,CAAA,QAAA,EACA,OACuD,EAAA;AACvD,IAAA,MAAM,UAAU,MAAM,IAAA,CAAK,eAAe,QAAU,EAAA,OAAA,IAAW,EAAE,CAAA;AACjE,IAAA,OAAO,EAAE,WAAa,EAAA,OAAA,CAAQ,WAAa,EAAA,KAAA,EAAO,QAAQ,KAAM,EAAA;AAAA;AAClE,EAEA,MAAM,WACJ,CAAA,YAAA,EACA,MACwB,EAAA;AACxB,IAAA,MAAM,IAAO,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAC1C,CAAA,KAAA,CAAM,cAAgB,EAAA,YAAY,CAClC,CAAA,KAAA,CAAM,QAAU,EAAA,MAAM,EACtB,KAAM,EAAA;AAET,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAO,OAAA,IAAA;AAAA;AAGT,IAAA,OAAO,IAAK,CAAA,IAAA;AAAA;AACd,EAEA,MAAM,mBACJ,YACoC,EAAA;AACpC,IAAA,MAAM,IAAO,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAC1C,CAAA,KAAA,CAAM,cAAgB,EAAA,YAAY,CAClC,CAAA,OAAA,CAAQ,MAAQ,EAAA,KAAK,EACrB,KAAM,EAAA;AAET,IAAO,OAAA,IAAA,GAAO,EAAE,MAAQ,EAAA,IAAA,CAAK,QAAQ,IAAM,EAAA,IAAA,CAAK,MAAS,GAAA,IAAA;AAAA;AAC3D,EAEA,MAAM,sBACJ,YACoC,EAAA;AACpC,IAAA,MAAM,IAAO,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAC1C,CAAA,KAAA,CAAM,cAAgB,EAAA,YAAY,CAClC,CAAA,OAAA,CAAQ,MAAQ,EAAA,MAAM,EACtB,KAAM,EAAA;AAET,IAAO,OAAA,IAAA,GAAO,EAAE,MAAQ,EAAA,IAAA,CAAK,QAAQ,IAAM,EAAA,IAAA,CAAK,MAAS,GAAA,IAAA;AAAA;AAC3D,EAEA,MAAM,mBACJ,CAAA,YAAA,EACA,MACoC,EAAA;AACpC,IAAA,MAAM,eAAkB,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,cAAc,MAAM,CAAA;AACnE,IAAA,IAAI,oBAAoB,IAAM,EAAA;AAC5B,MAAO,OAAA,IAAA;AAAA;AAGT,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,GAAG,kBAAkB,CAAA,CAC1C,MAAM,cAAgB,EAAA,YAAY,EAClC,KAAM,CAAA,MAAA,EAAQ,KAAK,eAAe,CAAA,CAClC,QAAQ,MAAQ,EAAA,KAAK,EACrB,KAAM,EAAA;AAET,IAAO,OAAA,IAAA,GAAO,EAAE,MAAQ,EAAA,IAAA,CAAK,QAAQ,IAAM,EAAA,IAAA,CAAK,MAAS,GAAA,IAAA;AAAA;AAC3D,EAEA,MAAM,uBACJ,CAAA,YAAA,EACA,MACoC,EAAA;AACpC,IAAA,MAAM,eAAkB,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,cAAc,MAAM,CAAA;AACnE,IAAA,IAAI,oBAAoB,IAAM,EAAA;AAC5B,MAAO,OAAA,IAAA;AAAA;AAGT,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,GAAG,kBAAkB,CAAA,CAC1C,MAAM,cAAgB,EAAA,YAAY,EAClC,KAAM,CAAA,MAAA,EAAQ,KAAK,eAAe,CAAA,CAClC,QAAQ,MAAQ,EAAA,MAAM,EACtB,KAAM,EAAA;AAET,IAAO,OAAA,IAAA,GAAO,EAAE,MAAQ,EAAA,IAAA,CAAK,QAAQ,IAAM,EAAA,IAAA,CAAK,MAAS,GAAA,IAAA;AAAA;AAC3D,EAEA,MAAM,cAAA,CACJ,YACA,EAAA,MAAA,EACA,IACe,EAAA;AACf,IAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC7B,MAAM,cAAgB,EAAA,YAAY,CAClC,CAAA,KAAA,CAAM,UAAU,MAAM,CAAA,CACtB,MAAO,CAAA,EAAE,MAAM,CAAA;AAAA;AACpB,EAEA,MAAM,mBAAA,CACJ,QACA,EAAA,EAAA,EACA,QACA,OAC4B,EAAA;AAC5B,IAAM,MAAA,IAAA,CAAK,GACR,MAAO,CAAA;AAAA,MACN,YAAc,EAAA,EAAA;AAAA,MACd;AAAA,KACD,CACA,CAAA,IAAA,CAAK,kBAAkB,CAAA;AAC1B,IAAM,MAAA,IAAA,CAAK,EAAG,CAAA,aAAa,CAAE,CAAA,KAAA,CAAM,MAAM,EAAE,CAAA,CAAE,SAAU,CAAA,YAAA,EAAc,CAAC,CAAA;AACtE,IAAA,OAAO,IAAK,CAAA,aAAA,CAAc,QAAU,EAAA,EAAA,EAAI,OAAO,CAAA;AAAA;AACjD,EAEA,MAAM,wBAAA,CACJ,QACA,EAAA,EAAA,EACA,QACA,OAC4B,EAAA;AAC5B,IAAA,MAAM,IAAO,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAC1C,CAAA,KAAA,CAAM,cAAgB,EAAA,EAAE,CACxB,CAAA,KAAA,CAAM,QAAU,EAAA,MAAM,EACtB,MAAO,EAAA;AACV,IAAA,IAAI,OAAO,CAAG,EAAA;AACZ,MAAM,MAAA,IAAA,CAAK,EAAG,CAAA,aAAa,CAAE,CAAA,KAAA,CAAM,MAAM,EAAE,CAAA,CAAE,SAAU,CAAA,YAAA,EAAc,CAAC,CAAA;AAAA;AAExE,IAAA,OAAO,IAAK,CAAA,aAAA,CAAc,QAAU,EAAA,EAAA,EAAI,OAAO,CAAA;AAAA;AACjD,EAEA,MAAM,sBAAsB,YAAyC,EAAA;AACnE,IAAM,MAAA,KAAA,GAAQ,MAAM,IAAA,CAAK,EAAG,CAAA,kBAAkB,CAC3C,CAAA,KAAA,CAAM,cAAgB,EAAA,YAAY,CAClC,CAAA,MAAA,CAAO,SAAS,CAAA;AACnB,IAAA,OAAO,KAAM,CAAA,GAAA,CAAI,CAAQ,IAAA,KAAA,IAAA,CAAK,OAAO,CAAA;AAAA;AACvC,EAEA,MAAM,sBAAsB,YAAsB,EAAA;AAChD,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,iBAAkB,CAAA,CAAC,YAAY,CAAC,CAAA;AACxD,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,qBAAsB,CAAA,CAAC,YAAY,CAAC,CAAA;AAChE,IAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,kBAAmB,CAAA,CAAC,YAAY,CAAC,CAAA;AAE1D,IAAA,MAAM,cAAiB,GAAA,IAAA,CAAK,GAAI,CAAA,YAAY,KAAK,EAAC;AAClD,IAAA,MAAM,kBAAqB,GAAA,QAAA,CAAS,GAAI,CAAA,YAAY,KAAK,EAAC;AAC1D,IAAA,MAAM,eAAkB,GAAA,KAAA,CAAM,GAAI,CAAA,YAAY,KAAK,EAAC;AAEpD,IACE,IAAA,cAAA,CAAe,WAAW,CAC1B,IAAA,kBAAA,CAAmB,WAAW,CAC9B,IAAA,eAAA,CAAgB,WAAW,CAC3B,EAAA;AACA,MAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC7B,KAAM,CAAA,cAAA,EAAgB,YAAY,CAAA,CAClC,KAAM,CAAA,WAAA,EAAa,IAAI,CAAA,CACvB,MAAO,EAAA;AACV,MAAA;AAAA;AAGF,IAAM,MAAA,KAAA,GAAQ,MAAM,IAAA,CAAK,EAAG,CAAA,OAAO,CAChC,CAAA,QAAA,CAAS,WAAa,EAAA,UAAA,EAAY,kBAAkB,CAAA,CACpD,QAAS,CAAA,MAAA,EAAQ,iBAAmB,EAAA,SAAS,CAC7C,CAAA,QAAA,CAAS,eAAiB,EAAA,UAAA,EAAY,sBAAsB,CAAA,CAC5D,QAAS,CAAA,UAAA,EAAY,wBAA0B,EAAA,aAAa,CAC5D,CAAA,KAAA,CAAM,CAAW,OAAA,KAAA;AAChB,MAAI,IAAA,cAAA,CAAe,SAAS,CAAG,EAAA;AAC7B,QAAQ,OAAA,CAAA,SAAA,CAAU,YAAY,cAAc,CAAA;AAAA;AAE9C,MAAI,IAAA,kBAAA,CAAmB,SAAS,CAAG,EAAA;AACjC,QAAQ,OAAA,CAAA,SAAA,CAAU,uBAAuB,kBAAkB,CAAA;AAAA;AAE7D,MAAI,IAAA,eAAA,CAAgB,SAAS,CAAG,EAAA;AAC9B,QAAQ,OAAA,CAAA,SAAA,CAAU,gBAAgB,eAAe,CAAA;AAAA;AACnD,KACD,CAAA,CACA,MAAO,CAAA,UAAU,EACjB,QAAS,EAAA;AAEZ,IAAA,MAAM,OAAU,GAAA,KAAA,CAAM,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA;AACnC,IAAI,IAAA,OAAA,CAAQ,SAAS,CAAG,EAAA;AACtB,MAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,QACZ,OAAA,CAAQ,GAAI,CAAA,OAAM,MAAU,KAAA;AAC1B,UAAM,MAAA,IAAA,CAAK,GACR,MAAO,CAAA;AAAA,YACN,YAAA;AAAA,YACA,MAAA;AAAA,YACA,SAAW,EAAA;AAAA,WACZ,CACA,CAAA,IAAA,CAAK,kBAAkB,CAAA,CACvB,UAAW,CAAA,CAAC,cAAgB,EAAA,QAAQ,CAAC,CAAA,CACrC,MAAO,EAAA;AAAA,SACX;AAAA,OACH;AAAA;AAGF,IAAM,MAAA,WAAA,GAAc,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC3C,KAAM,CAAA,cAAA,EAAgB,YAAY,CAAA,CAClC,KAAM,CAAA,WAAA,EAAa,IAAI,CAAA;AAE1B,IAAI,IAAA,OAAA,CAAQ,SAAS,CAAG,EAAA;AACtB,MAAY,WAAA,CAAA,UAAA,CAAW,UAAU,OAAO,CAAA;AAAA;AAG1C,IAAA,MAAM,YAAY,MAAO,EAAA;AACzB,IAAA,MAAM,KAAQ,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC3C,KAAM,CAAA,cAAA,EAAgB,YAAY,CAAA,CAClC,KAAM,CAAA,UAAU,EAChB,KAAM,EAAA;AACT,IAAA,MAAM,IAAK,CAAA,EAAA,CAAG,aAAa,CAAA,CACxB,MAAM,IAAM,EAAA,YAAY,CACxB,CAAA,MAAA,CAAO,YAAc,EAAA,IAAA,CAAK,YAAc,CAAA,KAAA,EAAe,GAAG,CAAC,CAAA;AAAA;AAChE,EAEA,MAAM,sBAAsB,MAAgB,EAAA;AAC1C,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,UAAW,CAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAErD,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAA;AAAA;AAGF,IAAM,MAAA,QAAA,GAAW,IAAK,CAAA,IAAA,IAAQ,EAAC;AAC/B,IAAM,MAAA,YAAA,GAAe,IAAK,CAAA,QAAA,IAAY,EAAC;AACvC,IAAA,MAAM,aAAa,IAAK,CAAA,MAAA;AAExB,IAAA,MAAM,WAAc,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,aAAa,CAC5C,CAAA,QAAA;AAAA,MACC,iBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA,KAED,CAAA,QAAA,CAAS,MAAQ,EAAA,uBAAA,EAAyB,SAAS,CACnD,CAAA,QAAA;AAAA,MACC,qBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA,KAED,CAAA,QAAA,CAAS,UAAY,EAAA,8BAAA,EAAgC,aAAa,CAClE,CAAA,QAAA;AAAA,MACC,kBAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA,KACF,CACC,MAAM,CAAW,OAAA,KAAA;AAChB,MAAI,IAAA,QAAA,CAAS,SAAS,CAAG,EAAA;AACvB,QAAQ,OAAA,CAAA,SAAA,CAAU,YAAY,QAAQ,CAAA;AAAA;AAExC,MAAI,IAAA,YAAA,CAAa,SAAS,CAAG,EAAA;AAC3B,QAAQ,OAAA,CAAA,SAAA,CAAU,uBAAuB,YAAY,CAAA;AAAA;AAEvD,MAAA,IAAI,UAAY,EAAA;AACd,QAAQ,OAAA,CAAA,OAAA,CAAQ,4BAA4B,UAAU,CAAA;AAAA;AACxD,KACD,CAAA,CACA,MAAO,CAAA,gBAAgB,EACvB,QAAS,EAAA;AAEZ,IAAA,MAAM,aAAgB,GAAA,WAAA,CAAY,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA;AAE/C,IAAI,IAAA,aAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,MAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,QACZ,aAAA,CAAc,GAAI,CAAA,OAAM,YAAgB,KAAA;AACtC,UAAM,MAAA,IAAA,CAAK,GACR,MAAO,CAAA;AAAA,YACN,YAAA;AAAA,YACA,MAAA;AAAA,YACA,SAAW,EAAA;AAAA,WACZ,CACA,CAAA,IAAA,CAAK,kBAAkB,CAAA,CACvB,UAAW,CAAA,CAAC,cAAgB,EAAA,QAAQ,CAAC,CAAA,CACrC,MAAO,EAAA;AAAA,SACX;AAAA,OACH;AAAA;AAGF,IAAM,MAAA,WAAA,GAAc,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC3C,KAAM,CAAA,QAAA,EAAU,MAAM,CAAA,CACtB,KAAM,CAAA,WAAA,EAAa,IAAI,CAAA;AAE1B,IAAI,IAAA,aAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,MAAY,WAAA,CAAA,UAAA,CAAW,gBAAgB,aAAa,CAAA;AAAA;AAGtD,IAAA,MAAM,YAAY,MAAO,EAAA;AAEzB,IAAI,IAAA,aAAA,CAAc,SAAS,CAAG,EAAA;AAC5B,MAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,QACZ,aAAA,CAAc,GAAI,CAAA,OAAM,YAAgB,KAAA;AACtC,UAAA,MAAM,KAAQ,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC3C,KAAM,CAAA,cAAA,EAAgB,YAAY,CAAA,CAClC,KAAM,CAAA,UAAU,EAChB,KAAM,EAAA;AACT,UAAA,MAAM,IAAK,CAAA,EAAA,CAAG,aAAa,CAAA,CACxB,MAAM,IAAM,EAAA,YAAY,CACxB,CAAA,MAAA,CAAO,YAAc,EAAA,IAAA,CAAK,YAAc,CAAA,KAAA,EAAe,GAAG,CAAC,CAAA;AAAA,SAC/D;AAAA,OACH;AAAA;AACF;AACF,EAEA,MAAM,gBACJ,CAAA,QAAA,EACA,YACkB,EAAA;AAClB,IAAM,MAAA,IAAA,CAAK,GACR,MAAO,CAAA;AAAA,MACN,OAAS,EAAA,QAAA;AAAA,MACT;AAAA,KACD,CACA,CAAA,IAAA,CAAK,kBAAkB,CAAA;AAC1B,IAAO,OAAA,IAAA;AAAA;AACT,EAEA,MAAM,kBACJ,CAAA,QAAA,EACA,YACkB,EAAA;AAClB,IAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC7B,KAAM,CAAA,SAAA,EAAW,QAAQ,CAAA,CACzB,KAAM,CAAA,cAAA,EAAgB,YAAY,CAAA,CAClC,MAAO,EAAA;AACV,IAAO,OAAA,IAAA;AAAA;AACT,EAEA,MAAM,kBAAkB,GAA6C,EAAA;AACnE,IAAI,IAAA,GAAA,CAAI,WAAW,CAAG,EAAA;AACpB,MAAA,2BAAW,GAAI,EAAA;AAAA;AAEjB,IAAA,MAAM,YAAY,MAAM,IAAA,CAAK,EAAG,CAAA,kBAAkB,EAC/C,MAAO,CAAA,cAAc,CACrB,CAAA,KAAA,CAAM,YAAY,CAClB,CAAA,OAAA,CAAQ,gBAAgB,GAAG,CAAA,CAC3B,QAAQ,cAAc,CAAA;AAEzB,IAAM,MAAA,MAAA,uBAAa,GAAoB,EAAA;AACvC,IAAU,SAAA,CAAA,OAAA,CAAQ,CAAC,CAAW,KAAA;AAC5B,MAAA,MAAA,CAAO,IAAI,CAAE,CAAA,YAAA,EAAc,KAAK,YAAa,CAAA,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,KACtD,CAAA;AACD,IAAO,OAAA,MAAA;AAAA;AACT,EAEA,MAAc,qBAAA,CACZ,IACA,EAAA,QAAA,EACA,OACuB,EAAA;AACvB,IAAI,IAAA,IAAA,CAAK,WAAW,CAAG,EAAA;AACrB,MAAA,OAAO,EAAC;AAAA;AAGV,IAAA,MAAM,aAAgB,GAAA,IAAA,CAAK,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA;AACxC,IAAM,MAAA;AAAA,MACJ,WAAA;AAAA,MACA,YAAe,GAAA,IAAA;AAAA,MACf,cAAiB,GAAA;AAAA,KACnB,GAAI,WAAW,EAAC;AAEhB,IAAM,MAAA,CAAC,KAAO,EAAA,WAAA,EAAa,SAAW,EAAA,OAAA,EAAS,IAAM,EAAA,QAAA,EAAU,KAAK,CAAA,GAClE,MAAM,OAAA,CAAQ,GAAI,CAAA;AAAA,MAChB,YAAgB,IAAA,IAAA,CAAK,UACjB,GAAA,IAAA,CAAK,UAAW,CAAA,QAAA;AAAA,QACd,QAAA;AAAA,QACA,EAAE,iBAAiB,IAAK,EAAA;AAAA,QACxB,WAAA;AAAA,QACA;AAAA,UACE,YAAY,OAAS,EAAA,UAAA;AAAA,UACrB,eAAiB,EAAA,KAAA;AAAA,UACjB,cAAgB,EAAA,KAAA;AAAA,UAChB,kBAAoB,EAAA,KAAA;AAAA,UACpB,YAAc,EAAA,KAAA;AAAA,UACd,YAAc,EAAA,KAAA;AAAA,UACd,gBAAgB,cAAkB,IAAA,KAAA;AAAA,UAClC,aAAe,EAAA,KAAA;AAAA,UACf,WAAa,EAAA,IAAA;AAAA,UACb,kBAAoB,EAAA,IAAA;AAAA,UACpB;AAAA;AACF,OAEF,GAAA,EAAE,KAAO,EAAA,EAAG,EAAA;AAAA,MAChB,IAAK,CAAA,gBAAA,CAAiB,cAAe,CAAA,aAAA,EAAe,cAAc,CAAA;AAAA,MAClE,IAAA,CAAK,kBAAkB,aAAa,CAAA;AAAA,MACpC,cACI,GAAA,IAAA,CAAK,EAAG,CAAA,aAAa,EAClB,QAAS,CAAA,MAAA,EAAQ,mBAAqB,EAAA,SAAS,CAC/C,CAAA,QAAA,CAAS,WAAa,EAAA,iBAAA,EAAmB,SAAS,CAClD,CAAA,QAAA;AAAA,QACC,kBAAA;AAAA,QACA,yBAAA;AAAA,QACA;AAAA,OACF,CACC,QAAQ,+BAAiC,EAAA,aAAa,EACtD,MAAO,CAAA,+BAAA,EAAiC,uBAAuB,CAClE,GAAA,KAAA,CAAA;AAAA,MACJ,IAAA,CAAK,kBAAkB,aAAa,CAAA;AAAA,MACpC,IAAA,CAAK,sBAAsB,aAAa,CAAA;AAAA,MACxC,IAAA,CAAK,mBAAmB,aAAa;AAAA,KACtC,CAAA;AAEH,IAAM,MAAA,QAAA,uBAAe,GAAmB,EAAA;AACxC,IAAM,KAAA,CAAA,KAAA,EAAO,OAAQ,CAAA,CAAC,CAAW,KAAA;AAC/B,MAAA,IAAI,EAAE,aAAiB,IAAA,KAAA,CAAM,OAAQ,CAAA,CAAA,CAAE,aAAa,CAAG,EAAA;AACrD,QAAE,CAAA,CAAA,aAAA,CAAc,OAAQ,CAAA,CAAC,YAAyB,KAAA;AAChD,UAAA,MAAM,EAAK,GAAA,QAAA,CAAS,GAAI,CAAA,YAAY,KAAK,EAAC;AAC1C,UAAA,EAAA,CAAG,KAAK,CAAC,CAAA;AACT,UAAS,QAAA,CAAA,GAAA,CAAI,cAAc,EAAE,CAAA;AAAA,SAC9B,CAAA;AAAA;AACH,KACD,CAAA;AAED,IAAM,MAAA,cAAA,GAAiB,WAAe,oBAAA,IAAI,GAAsB,EAAA;AAEhE,IAAM,MAAA,YAAA,GAAe,SAAa,oBAAA,IAAI,GAAoB,EAAA;AAE1D,IAAM,MAAA,UAAA,uBAAiB,GAAsB,EAAA;AAC7C,IAAS,OAAA,EAAA,OAAA,CAAQ,CAAC,CAAW,KAAA;AAC3B,MAAA,MAAM,KAAK,UAAW,CAAA,GAAA,CAAI,CAAE,CAAA,YAAY,KAAK,EAAC;AAC9C,MAAG,EAAA,CAAA,IAAA,CAAK,EAAE,SAAS,CAAA;AACnB,MAAW,UAAA,CAAA,GAAA,CAAI,CAAE,CAAA,YAAA,EAAc,EAAE,CAAA;AAAA,KAClC,CAAA;AAED,IAAO,OAAA,IAAA,CAAK,IAAI,CAAO,GAAA,KAAA;AACrB,MAAA,MAAM,kBAAkB,QAAS,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,KAAK,EAAC;AACjD,MAAA,MAAM,eAAeC,cAAQ,CAAA;AAAA,QAC3B,GAAG,IAAI,GAAA,CAAI,eAAgB,CAAA,GAAA,CAAI,CAAC,CAAA,KAAW,CAAE,CAAA,QAAQ,CAAE,CAAA,IAAA,EAAM;AAAA,OAC9D,CAAA;AACD,MAAA,MAAM,WAAWA,cAAQ,CAAA;AAAA,QACvB,GAAG,IAAI,GAAA,CAAI,eAAgB,CAAA,GAAA,CAAI,CAAC,CAAA,KAAW,CAAE,CAAA,IAAI,CAAE,CAAA,IAAA,EAAM;AAAA,OAC1D,CAAA;AAED,MAAO,OAAA;AAAA,QACL,IAAI,GAAI,CAAA,EAAA;AAAA,QACR,OAAO,GAAI,CAAA,KAAA;AAAA,QACX,OAAO,GAAI,CAAA,KAAA;AAAA,QACX,aAAa,GAAI,CAAA,WAAA;AAAA,QACjB,SAAS,GAAI,CAAA,OAAA;AAAA,QACb,KAAO,EAAA,eAAA;AAAA,QACP,aAAa,GAAI,CAAA,WAAA;AAAA,QACjB,UAAY,EAAA,IAAA,CAAK,YAAa,CAAA,GAAA,CAAI,UAAU,CAAA;AAAA,QAC5C,cAAgB,EAAA,IAAA,CAAK,YAAa,CAAA,GAAA,CAAI,cAAc,CAAA;AAAA,QACpD,aAAe,EAAA,IAAA,CAAK,YAAa,CAAA,GAAA,CAAI,aAAa,CAAA;AAAA,QAClD,UAAY,EAAA,IAAA,CAAK,YAAa,CAAA,GAAA,CAAI,UAAU,CAAA;AAAA,QAC5C,UAAU,QAAS,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,KAAK,EAAC;AAAA,QACnC,MAAM,IAAK,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,KAAK,EAAC;AAAA,QAC3B,OAAO,KAAM,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,KAAK,EAAC;AAAA,QAC7B,YAAA;AAAA,QACA,QAAA;AAAA,QACA,QAAQ,cAAe,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,KAAK,EAAC;AAAA,QACvC,SAAW,EAAA,YAAA,CAAa,GAAI,CAAA,GAAA,CAAI,EAAE,CAAK,IAAA,CAAA;AAAA,QACvC,OAAS,EAAA,UAAA,CAAW,GAAI,CAAA,GAAA,CAAI,EAAE;AAAA,OAChC;AAAA,KACD,CAAA;AAAA;AACH,EAEA,MAAM,kBAAkB,GAA+C,EAAA;AACrE,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,EAAG,CAAA,iBAAiB,EACzC,QAAS,CAAA,MAAA,EAAQ,uBAAyB,EAAA,SAAS,EACnD,OAAQ,CAAA,8BAAA,EAAgC,GAAG,CAC3C,CAAA,MAAA,CAAO,gCAAgC,UAAU,CAAA;AAEpD,IAAM,MAAA,MAAA,uBAAa,GAAsB,EAAA;AACzC,IAAA,IAAA,CAAK,QAAQ,CAAO,GAAA,KAAA;AAClB,MAAA,MAAM,OAAO,MAAO,CAAA,GAAA,CAAI,GAAI,CAAA,YAAY,KAAK,EAAC;AAC9C,MAAK,IAAA,CAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACjB,MAAO,MAAA,CAAA,GAAA,CAAI,GAAI,CAAA,YAAA,EAAc,IAAI,CAAA;AAAA,KAClC,CAAA;AACD,IAAO,OAAA,MAAA;AAAA;AACT,EAEA,MAAM,sBAAsB,GAA+C,EAAA;AACzE,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,EAAG,CAAA,qBAAqB,EAC7C,QAAS,CAAA,UAAA,EAAY,8BAAgC,EAAA,aAAa,EAClE,OAAQ,CAAA,kCAAA,EAAoC,GAAG,CAC/C,CAAA,MAAA,CAAO,oCAAoC,qBAAqB,CAAA;AAEnE,IAAM,MAAA,MAAA,uBAAa,GAAsB,EAAA;AACzC,IAAA,IAAA,CAAK,QAAQ,CAAO,GAAA,KAAA;AAClB,MAAA,MAAM,WAAW,MAAO,CAAA,GAAA,CAAI,GAAI,CAAA,YAAY,KAAK,EAAC;AAClD,MAAS,QAAA,CAAA,IAAA,CAAK,IAAI,UAAU,CAAA;AAC5B,MAAO,MAAA,CAAA,GAAA,CAAI,GAAI,CAAA,YAAA,EAAc,QAAQ,CAAA;AAAA,KACtC,CAAA;AACD,IAAO,OAAA,MAAA;AAAA;AACT,EAEA,MAAM,mBAAmB,GAA+C,EAAA;AACtE,IAAA,MAAM,IAAO,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC1C,OAAQ,CAAA,cAAA,EAAgB,GAAG,CAAA,CAC3B,MAAO,CAAA,cAAA,EAAgB,SAAS,CAAA;AAEnC,IAAM,MAAA,MAAA,uBAAa,GAAsB,EAAA;AACzC,IAAA,IAAA,CAAK,QAAQ,CAAO,GAAA,KAAA;AAClB,MAAA,MAAM,QAAQ,MAAO,CAAA,GAAA,CAAI,GAAI,CAAA,YAAY,KAAK,EAAC;AAC/C,MAAM,KAAA,CAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AACtB,MAAO,MAAA,CAAA,GAAA,CAAI,GAAI,CAAA,YAAA,EAAc,KAAK,CAAA;AAAA,KACnC,CAAA;AACD,IAAO,OAAA,MAAA;AAAA;AACT,EAEQ,uBAA0B,GAAA;AAChC,IAAM,MAAA,cAAA,GAAiB,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC9C,QAAS,CAAA,OAAA,EAAS,yBAA2B,EAAA,UAAU,CACvD,CAAA,KAAA,CAAM,+BAAiC,EAAA,IAAA,CAAK,GAAG,GAAI,CAAA,gBAAgB,CAAC,CAAA,CACpE,KAAM,CAAA,YAAA,EAAc,UAAU,CAAA,CAC9B,KAAM,CAAA,GAAG,CACT,CAAA,EAAA,CAAG,gBAAgB,CAAA;AAEtB,IAAM,MAAA,aAAA,GAAgB,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC7C,QAAS,CAAA,OAAA,EAAS,yBAA2B,EAAA,UAAU,CACvD,CAAA,KAAA,CAAM,+BAAiC,EAAA,IAAA,CAAK,GAAG,GAAI,CAAA,gBAAgB,CAAC,CAAA,CACpE,KAAM,CAAA,YAAA,EAAc,SAAS,CAAA,CAC7B,KAAM,CAAA,GAAG,CACT,CAAA,EAAA,CAAG,eAAe,CAAA;AAErB,IAAM,MAAA,UAAA,GAAa,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC1C,QAAS,CAAA,OAAA,EAAS,yBAA2B,EAAA,UAAU,CACvD,CAAA,KAAA,CAAM,+BAAiC,EAAA,IAAA,CAAK,GAAG,GAAI,CAAA,gBAAgB,CAAC,CAAA,CACpE,KAAM,CAAA,YAAA,EAAc,MAAM,CAAA,CAC1B,KAAM,CAAA,GAAG,CACT,CAAA,EAAA,CAAG,YAAY,CAAA;AAElB,IAAA,MAAM,gBAAgB,IAAK,CAAA,EAAA,CAAG,kBAAkB,CAAA,CAC7C,MAAM,+BAAiC,EAAA,IAAA,CAAK,EAAG,CAAA,GAAA,CAAI,gBAAgB,CAAC,CAAA,CACpE,MAAM,GAAG,CAAA,CACT,GAAG,eAAe,CAAA;AAErB,IAAO,OAAA,IAAA,CAAK,EAAwB,CAAA,aAAa,CAC9C,CAAA,MAAA;AAAA,MACC,eAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF,CACC,QAAQ,gBAAgB,CAAA;AAAA;AAC7B,EAEA,MAAc,iBAAA,CACZ,EACA,EAAA,SAAA,EACA,SACA,EAAA;AACA,IAAM,MAAA,IAAA,GAAOC,qCAAW,SAAS,CAAA;AACjC,IAAA,IAAI,SAAW,EAAA;AACb,MAAM,MAAA,IAAA,CAAK,GAAG,iBAAiB,CAAA,CAAE,MAAM,cAAgB,EAAA,GAAA,EAAK,EAAE,CAAA,CAAE,MAAO,EAAA;AAAA;AAGzE,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,KAAW,CAAG,EAAA;AAC9B,MAAA;AAAA;AAGF,IAAA,MAAM,YAAe,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,MAAM,CAAA,CACtC,OAAQ,CAAA,KAAA,EAAO,IAAI,CAAA,CACnB,SAAU,CAAA,IAAI,EACd,MAAO,EAAA;AACV,IAAM,MAAA,OAAA,GAAU,IAAK,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAC,YAAa,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,GAAQ,KAAA,CAAC,CAAC,CAAA;AACrE,IAAA,MAAM,OAAkC,GAAA;AAAA,MACtC,GAAGC,UAAA;AAAA,MACH,GAAI,MAAM,IAAK,CAAA,WAAA,EAAa,OAAQ;AAAA,KACtC;AAEA,IAAM,MAAA,MAAA,GAAA,CACJ,MAAM,OAAQ,CAAA,GAAA;AAAA,MACZ,CAAC,GAAG,IAAI,GAAA,CAAI,OAAO,CAAC,CAAA,CAAE,GAAI,CAAA,OAAM,GAAO,KAAA;AACrC,QAAM,MAAA,OAAA,GAAU,IAAI,IAAK,EAAA;AACzB,QAAA,MAAM,WAAc,GAAA,OAAA,IAAW,OAAU,GAAA,OAAA,CAAQ,OAAO,CAAI,GAAA,KAAA,CAAA;AAE5D,QAAA,OAAO,KAAK,EACT,CAAA,MAAA,CAAO,EAAE,GAAK,EAAA,OAAA,EAAS,aAAa,CAAA,CACpC,IAAK,CAAA,MAAM,EACX,SAAU,CAAA,IAAI,EACd,UAAW,CAAA,KAAK,EAChB,MAAO,EAAA;AAAA,OACX;AAAA,KAGF,EAAA,IAAA,EACA,CAAA,GAAA,CAAI,SAAO,GAAI,CAAA,EAAE,CACjB,CAAA,MAAA,CAAO,YAAa,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,EAAE,CAAC,CAAA;AAErC,IAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,MACZ,MAAA,CAAO,GAAI,CAAA,OAAM,KAAS,KAAA;AACxB,QAAA,MAAM,IAAK,CAAA,EAAA,CACR,MAAO,CAAA,EAAE,cAAc,EAAI,EAAA,KAAA,EAAO,CAAA,CAClC,IAAK,CAAA,iBAAiB,CACtB,CAAA,UAAA,GACA,MAAO,EAAA;AAAA,OACX;AAAA,KACH;AAAA;AACF,EAEA,MAAc,qBAAA,CACZ,EACA,EAAA,aAAA,EACA,SACA,EAAA;AACA,IAAA,IAAI,SAAW,EAAA;AACb,MAAM,MAAA,IAAA,CAAK,GAAG,qBAAqB,CAAA,CAChC,MAAM,cAAgB,EAAA,GAAA,EAAK,EAAE,CAAA,CAC7B,MAAO,EAAA;AAAA;AAGZ,IAAA,MAAM,KAAQ,GAAA,cAAA;AACd,IAAM,MAAA,QAAA,GACJ,eACI,MAAO,CAAA,CAAA,CAAA,KAAK,MAAM,IAAK,CAAA,CAAC,CAAC,CAC1B,CAAA,GAAA,CAAI,OAAK,CAAE,CAAA,WAAA,EAAa,CACxB,CAAA,MAAA,CAAO,OAAK,CAAE,CAAA,MAAA,GAAS,CAAC,CAAA,IAAK,EAAC;AAEnC,IAAA,IAAI,CAAC,QAAA,IAAY,QAAS,CAAA,MAAA,KAAW,CAAG,EAAA;AACtC,MAAA;AAAA;AAGF,IAAA,MAAM,gBAAmB,GAAA,MAAM,IAAK,CAAA,EAAA,CAAG,UAAU,CAAA,CAC9C,OAAQ,CAAA,YAAA,EAAc,QAAQ,CAAA,CAC9B,SAAU,CAAA,IAAI,EACd,MAAO,EAAA;AACV,IAAA,MAAM,cAAc,QAAS,CAAA,MAAA;AAAA,MAC3B,OAAK,CAAC,gBAAA,CAAiB,KAAK,CAAK,CAAA,KAAA,CAAA,CAAE,eAAe,CAAC;AAAA,KACrD;AAEA,IAAM,MAAA,SAAA,GAAA,CACJ,MAAM,OAAQ,CAAA,GAAA;AAAA,MACZ,CAAC,GAAG,IAAI,GAAI,CAAA,WAAW,CAAC,CAAE,CAAA,GAAA;AAAA,QAAI,OAAM,SAClC,KAAA,IAAA,CAAK,GACF,MAAO,CAAA,EAAE,YAAY,SAAU,EAAC,EAChC,IAAK,CAAA,UAAU,EACf,SAAU,CAAA,IAAI,EACd,UAAW,CAAA,YAAY,EACvB,MAAO;AAAA;AACZ,KAGD,EAAA,IAAA,EACA,CAAA,GAAA,CAAI,YAAU,MAAO,CAAA,EAAE,CACvB,CAAA,MAAA,CAAO,gBAAiB,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,EAAE,CAAC,CAAA;AAEzC,IAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,MACZ,SAAA,CAAU,GAAI,CAAA,OAAM,QAAY,KAAA;AAC9B,QAAA,MAAM,IAAK,CAAA,EAAA,CACR,MAAO,CAAA,EAAE,cAAc,EAAI,EAAA,QAAA,EAAU,CAAA,CACrC,IAAK,CAAA,qBAAqB,CAC1B,CAAA,UAAA,GACA,MAAO,EAAA;AAAA,OACX;AAAA,KACH;AAAA;AACF,EAEA,MAAc,kBAAA,CACZ,EACA,EAAA,UAAA,EACA,SACA,EAAA;AACA,IAAA,IAAI,SAAW,EAAA;AACb,MAAM,MAAA,IAAA,CAAK,GAAG,kBAAkB,CAAA,CAAE,MAAM,cAAgB,EAAA,GAAA,EAAK,EAAE,CAAA,CAAE,MAAO,EAAA;AAAA;AAG1E,IAAA,MAAM,KAAQ,GAAA,CAAC,GAAG,IAAI,IAAI,UAAY,EAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,CAAE,MAAS,GAAA,CAAC,CAAK,IAAA,EAAE,CAAC,CAAA;AAEtE,IAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,MAAA;AAAA;AAGF,IAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,MACZ,KAAA,CAAM,GAAI,CAAA,OAAM,OAAW,KAAA;AACzB,QAAM,MAAA,IAAA,CAAK,EACR,CAAA,MAAA,CAAO,EAAE,YAAA,EAAc,IAAI,OAAQ,EAAC,CACpC,CAAA,IAAA,CAAK,kBAAkB,CAAA;AAAA,OAC3B;AAAA,KACH;AAAA;AAEJ;;;;"}
|
|
@@ -16,9 +16,13 @@ class PostsStore extends BaseStore.BaseStore {
|
|
|
16
16
|
this.tagDatabase = tagDatabase;
|
|
17
17
|
}
|
|
18
18
|
answersStore;
|
|
19
|
+
collectionsStore;
|
|
19
20
|
setAnswersStore(answersStore) {
|
|
20
21
|
this.answersStore = answersStore;
|
|
21
22
|
}
|
|
23
|
+
setCollectionsStore(collectionsStore) {
|
|
24
|
+
this.collectionsStore = collectionsStore;
|
|
25
|
+
}
|
|
22
26
|
async getAIAnswer(postId) {
|
|
23
27
|
const row = await this.db("post_ai_answers").where("postId", postId).first();
|
|
24
28
|
if (!row) {
|
|
@@ -459,6 +463,7 @@ class PostsStore extends BaseStore.BaseStore {
|
|
|
459
463
|
posts[0].id,
|
|
460
464
|
headerImage
|
|
461
465
|
);
|
|
466
|
+
await this.collectionsStore?.syncPostToCollections(posts[0].id);
|
|
462
467
|
return (await this.mapPostEntities([posts[0]], user_ref, opts))[0];
|
|
463
468
|
}
|
|
464
469
|
async updatePost(options) {
|
|
@@ -505,6 +510,7 @@ class PostsStore extends BaseStore.BaseStore {
|
|
|
505
510
|
id,
|
|
506
511
|
headerImage
|
|
507
512
|
);
|
|
513
|
+
await this.collectionsStore?.syncPostToCollections(id);
|
|
508
514
|
return await this.getPost(user_ref, id, false, opts);
|
|
509
515
|
}
|
|
510
516
|
async deletePost(id, permanently) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostsStore.cjs.js","sources":["../../../src/database/stores/PostsStore.ts"],"sourcesContent":["import {\n AIResponse,\n Answer,\n Comment as QetaComment,\n filterTags,\n Post,\n PostReview,\n PostsQuery,\n PostStatus,\n PostType,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { MaybePost, PostOptions, Posts } from '../QetaStore';\nimport { QetaFilters } from '../../service/util';\nimport { Knex } from 'knex';\nimport { AnswersStore } from './AnswersStore';\nimport { CommentsStore } from './CommentsStore';\nimport { TagsStore } from './TagsStore';\nimport { EntitiesStore } from './EntitiesStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport { TAGS } from '../../tagDb';\nimport { BaseStore } from './BaseStore';\nimport { TagDatabase } from '@drodil/backstage-plugin-qeta-node';\n\nimport { eng, removeStopwords } from 'stopword';\n\nexport interface RawPostEntity {\n id: number;\n author: string;\n title: string;\n content: string;\n status: string;\n created: Date | string;\n updated: Date | string;\n updatedBy: string;\n score: number | string;\n views: number | string;\n answersCount: number | string;\n correctAnswers: number | string;\n commentsCount: number | string;\n favorite: number | string;\n trend: number | string;\n anonymous: boolean;\n type: 'question' | 'article' | 'link';\n headerImage: string;\n url: string | null;\n published: Date | string | null;\n obsolete: number | string | boolean;\n last_interaction?: Date | string;\n}\n\nexport interface RawPostVoteEntity {\n postId: number;\n author: string;\n score: number;\n timestamp: Date;\n}\n\nexport interface RawPostAIAnswer {\n id: number;\n answer: string;\n created: Date;\n}\n\nexport class PostsStore extends BaseStore {\n private answersStore?: AnswersStore;\n\n constructor(\n protected readonly db: Knex,\n private readonly commentsStore: CommentsStore,\n private readonly tagsStore: TagsStore,\n private readonly entitiesStore: EntitiesStore,\n private readonly attachmentsStore: AttachmentsStore,\n private readonly tagDatabase?: TagDatabase,\n ) {\n super(db);\n }\n\n setAnswersStore(answersStore: AnswersStore) {\n this.answersStore = answersStore;\n }\n\n async getAIAnswer(postId: number): Promise<AIResponse | null> {\n const row = await this.db('post_ai_answers')\n .where('postId', postId)\n .first();\n if (!row) {\n return null;\n }\n return {\n answer: row.answer,\n created: row.created,\n };\n }\n\n async saveAIAnswer(postId: number, response: AIResponse): Promise<void> {\n await this.db\n .insert({\n postId,\n answer: response.answer,\n created: response.created,\n })\n .into('post_ai_answers')\n .onConflict('postId')\n .merge();\n }\n\n async deleteAIAnswer(postId: number): Promise<boolean> {\n const deleted = await this.db('post_ai_answers')\n .where('postId', postId)\n .del();\n return deleted > 0;\n }\n\n async reviewPost(\n user_ref: string,\n postId: number,\n status: 'valid' | 'obsolete',\n comment?: string,\n ): Promise<MaybePost> {\n await this.db('post_reviews').insert({\n post_id: postId,\n reviewer: user_ref,\n status,\n comment,\n created: new Date(),\n });\n\n if (status === 'obsolete') {\n await this.db('posts').where('id', postId).update({ status: 'obsolete' });\n } else {\n await this.db('posts').where('id', postId).update({ status: 'active' });\n }\n\n return this.getPost(user_ref, postId, false, {\n includeHealth: true,\n reviewThresholdMs: 15552000000, // 180 days default\n });\n }\n\n async getPostReviews(postId: number): Promise<PostReview[]> {\n const rows = await this.db('post_reviews')\n .where('post_id', postId)\n .orderBy('created', 'desc')\n .select('*');\n\n return rows.map(row => ({\n id: row.id,\n postId: row.post_id,\n reviewer: row.reviewer,\n status: row.status,\n comment: row.comment,\n created: new Date(row.created),\n }));\n }\n\n async getPosts(\n user_ref: string,\n options: PostsQuery,\n filters?: PermissionCriteria<QetaFilters>,\n opts?: PostOptions,\n ): Promise<Posts> {\n const {\n includeTotal = true,\n includeDraftFilter = true,\n includeHealth = false,\n } = opts ?? {};\n const query = this.getPostsBaseQuery(user_ref, options);\n if (options.type) {\n query.where('posts.type', options.type);\n }\n\n if (options.obsolete !== undefined) {\n if (options.obsolete) {\n query.where('posts.status', 'obsolete');\n } else {\n query.where(q => {\n q.whereNot('posts.status', 'obsolete');\n });\n }\n }\n\n if (options.fromDate && options.toDate) {\n query.whereBetween('posts.created', [\n `${options.fromDate} 00:00:00.000+00`,\n `${options.toDate} 23:59:59.999+00`,\n ]);\n } else if (options.fromDate) {\n query.where('posts.created', '>=', `${options.fromDate} 00:00:00.000+00`);\n } else if (options.toDate) {\n query.where('posts.created', '<=', `${options.toDate} 23:59:59.999+00`);\n }\n\n if (options.author) {\n if (Array.isArray(options.author)) {\n query.whereIn('posts.author', options.author);\n } else {\n query.where('posts.author', '=', options.author);\n }\n }\n\n if (options.excludeAuthors) {\n query.whereNotIn('posts.author', options.excludeAuthors);\n }\n\n if (options.status) {\n if (options.status === 'draft') {\n query.where('posts.author', '=', user_ref);\n }\n query.where('posts.status', '=', options.status);\n } else if (includeDraftFilter) {\n query.where(q => {\n q.whereIn('posts.status', ['active', 'obsolete']).orWhere(q2 => {\n q2.where('posts.status', 'draft').where(\n 'posts.author',\n '=',\n user_ref,\n );\n });\n });\n }\n\n if (filters) {\n this.parseFilter(filters, query, this.db);\n }\n\n if (options.searchQuery) {\n this.applySearchQuery(\n query,\n ['posts.title', 'posts.content'],\n options.searchQuery,\n );\n }\n\n if (options.tags) {\n const tags = filterTags(options.tags);\n if (options.tagsRelation === 'or') {\n query.innerJoin('post_tags', 'posts.id', 'post_tags.postId');\n query.innerJoin('tags', 'post_tags.tagId', 'tags.id');\n query.whereIn('tags.tag', tags);\n } else {\n tags?.forEach((t: string, i: number) => {\n query.innerJoin(`post_tags AS qt${i}`, 'posts.id', `qt${i}.postId`);\n query.innerJoin(`tags AS t${i}`, `qt${i}.tagId`, `t${i}.id`);\n query.where(`t${i}.tag`, '=', t);\n });\n }\n }\n\n if (options.entities) {\n const entityValues = Array.isArray(options.entities)\n ? options.entities\n : [options.entities];\n if (options.entitiesRelation === 'or') {\n query\n .innerJoin('post_entities', 'posts.id', 'post_entities.postId')\n .innerJoin('entities', 'post_entities.entityId', 'entities.id')\n .whereIn('entities.entity_ref', entityValues);\n } else {\n entityValues.forEach((t: string, i: number) => {\n query.innerJoin(\n `post_entities AS pe${i}`,\n 'posts.id',\n `pe${i}.postId`,\n );\n query.innerJoin(`entities AS e${i}`, `pe${i}.entityId`, `e${i}.id`);\n query.where(`e${i}.entity_ref`, '=', t);\n });\n }\n }\n\n if (options.collectionId) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.where('collection_posts.collectionId', options.collectionId);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (opts?.collectionIds) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.whereIn('collection_posts.collectionId', opts.collectionIds);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (options.orderBy === 'rank') {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.select('collection_posts.rank');\n }\n if (options.orderBy === 'rank') {\n if (this.db.client.config.client === 'pg') {\n query.groupBy(\n 'posts.id',\n 'collection_posts.rank',\n this.db.raw('user_favorite.\"postId\"'),\n );\n } else {\n query.groupBy(\n 'posts.id',\n 'collection_posts.rank',\n 'user_favorite.postId',\n );\n }\n }\n\n if (options.noAnswers) {\n query.where('answersCount', 0);\n }\n\n if (options.hasAnswers) {\n query.where('answersCount', '>', 0);\n }\n\n if (options.noCorrectAnswer) {\n query.where('correctAnswers', 0);\n }\n\n if (options.noVotes) {\n query.where('score', 0);\n }\n\n if (options.favorite) {\n query.where('user_favorite.user', '=', user_ref);\n query.whereNotNull('user_favorite.postId');\n }\n\n if (options.includeTrend || options.orderBy === 'trend') {\n query.select(\n this.db.raw(\n `(\n posts.score * 200 + \n posts.\"answersCount\" * 100 +\n posts.\"favoritesCount\" * 50 +\n posts.views * 10 +\n posts.\"commentsCount\" * 30\n ) / \n POWER(\n EXTRACT(EPOCH FROM (now() - posts.created)) / 172800 + 1,\n 1.5\n ) as trend`,\n ),\n );\n }\n\n if (includeHealth || options.reviewNeeded) {\n const func = this.db.client.config.client === 'pg' ? 'GREATEST' : 'MAX';\n const lastInteractionQuery = `${func}(\n posts.created,\n COALESCE((SELECT MAX(created) FROM answers WHERE answers.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM comments WHERE comments.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(ac.created) FROM answers a JOIN comments ac ON ac.\"answerId\" = a.id WHERE a.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM post_reviews WHERE post_reviews.post_id = posts.id), posts.created)\n )`;\n\n query.select(this.db.raw(`${lastInteractionQuery} as last_interaction`));\n\n const reviewThresholdMs = opts?.reviewThresholdMs || 0;\n if (options.reviewNeeded && reviewThresholdMs > 0) {\n const thresholdDate = new Date(Date.now() - reviewThresholdMs);\n const thresholdParam = thresholdDate.toISOString();\n query.whereRaw(`${lastInteractionQuery} < ?`, [thresholdParam]);\n }\n if (options.reviewNeeded) {\n query.whereNotIn('posts.status', ['deleted', 'obsolete']);\n }\n }\n\n if (options.ids) {\n query.whereIn('posts.id', options.ids);\n }\n\n const totalQuery = query.clone();\n\n if (options.random) {\n query.orderByRaw('RANDOM()');\n } else if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n } else {\n query.orderBy('created', 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n includeTotal\n ? this.db(totalQuery.as('totalQuery')).count('* as CNT').first()\n : undefined,\n ]);\n const rows = results[0] as RawPostEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n posts: await this.mapPostEntities(rows, user_ref, {\n ...opts,\n includeAnswers: options.includeAnswers ?? opts?.includeAnswers,\n includeVotes: options.includeVotes ?? opts?.includeVotes,\n includeEntities: options.includeEntities ?? opts?.includeEntities,\n includeAttachments:\n options.includeAttachments ?? opts?.includeAttachments,\n includeExperts: options.includeExperts ?? opts?.includeExperts,\n includeHealth: options.includeHealth ?? opts?.includeHealth,\n }),\n total,\n };\n }\n\n async suggestPosts(\n user_ref: string,\n title: string,\n content: string,\n tags?: string[],\n entities?: string[],\n filters?: PermissionCriteria<QetaFilters>,\n opts?: PostOptions,\n ): Promise<Posts> {\n const titleWords = removeStopwords(title.split(/\\s+/g), eng).join(' ');\n const contentWords = removeStopwords(content.split(/\\s+/g), eng).join(' ');\n\n const [titlePosts, contentPosts, tagPosts, entityPosts] = await Promise.all(\n [\n titleWords && titleWords.length > 0\n ? this.getPosts(\n user_ref,\n {\n searchQuery: titleWords,\n limit: 5,\n type: 'question',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n contentWords && contentWords.length > 0\n ? this.getPosts(\n user_ref,\n {\n searchQuery: contentWords,\n limit: 5,\n type: 'question',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n tags && tags.length > 0\n ? this.getPosts(\n user_ref,\n {\n limit: 5,\n type: 'question',\n tags: tags,\n tagsRelation: 'or',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n entities && entities.length > 0\n ? this.getPosts(\n user_ref,\n {\n limit: 5,\n type: 'question',\n entities: entities,\n entitiesRelation: 'or',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n ],\n );\n\n const allPosts = [\n ...titlePosts.posts,\n ...contentPosts.posts,\n ...tagPosts.posts,\n ...entityPosts.posts,\n ];\n\n const uniquePosts = Array.from(new Set(allPosts.map(p => p.id)))\n .map(id => allPosts.find(p => p.id === id))\n .filter((p): p is Post => p !== undefined);\n return { posts: uniquePosts.slice(0, 5), total: uniquePosts.length };\n }\n\n async getPost(\n user_ref: string,\n id: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const query = this.getPostsBaseQuery(user_ref).where('posts.id', '=', id);\n\n if (options?.includeHealth) {\n const func = this.db.client.config.client === 'pg' ? 'GREATEST' : 'MAX';\n const lastInteractionQuery = `${func}(\n posts.created,\n COALESCE((SELECT MAX(created) FROM answers WHERE answers.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM comments WHERE comments.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(ac.created) FROM answers a JOIN comments ac ON ac.\"answerId\" = a.id WHERE a.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM post_reviews WHERE post_reviews.post_id = posts.id), posts.created)\n )`;\n query.select(this.db.raw(`${lastInteractionQuery} as last_interaction`));\n }\n\n const rows = await query;\n\n if (!rows || rows.length === 0) {\n return null;\n }\n const post = rows[0] as unknown as RawPostEntity;\n\n if (recordView && post.status === 'active') {\n this.recordPostView(id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async getPostByAnswerId(\n user_ref: string,\n answerId: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const rows = await this.getPostsBaseQuery(user_ref)\n .join('answers', 'posts.id', 'answers.postId')\n .where('answers.id', '=', answerId)\n .select('posts.*');\n if (!rows || rows.length === 0) {\n return null;\n }\n if (recordView) {\n this.recordPostView(rows[0].id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async createPost(options: {\n user_ref: string;\n title: string;\n content: string;\n created: Date;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n anonymous?: boolean;\n type?: PostType;\n headerImage?: string;\n url?: string;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<Post> {\n const {\n user_ref,\n title,\n content,\n author,\n created,\n tags,\n entities,\n images,\n anonymous,\n type = 'question',\n headerImage,\n url,\n opts,\n status = 'active',\n } = options;\n const posts = await this.db\n .insert(\n {\n author: author ?? user_ref,\n title,\n content,\n created,\n anonymous: anonymous ?? false,\n type: type ?? 'question',\n headerImage,\n url,\n status,\n published: status === 'active' ? created : null,\n },\n ['id'],\n )\n .into('posts')\n .returning([\n 'id',\n 'author',\n 'title',\n 'content',\n 'created',\n 'anonymous',\n 'type',\n 'status',\n 'url',\n ]);\n\n await Promise.all([\n this.addTags(posts[0].id, tags),\n this.addEntities(posts[0].id, entities),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n posts[0].id,\n headerImage,\n );\n\n return (await this.mapPostEntities([posts[0]], user_ref, opts))[0];\n }\n\n async updatePost(options: {\n id: number;\n user_ref: string;\n title?: string;\n content?: string;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n headerImage?: string;\n url?: string;\n setUpdatedBy?: boolean;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<MaybePost> {\n const {\n id,\n user_ref,\n title,\n content,\n author,\n tags,\n entities,\n images,\n headerImage,\n url,\n setUpdatedBy = true,\n opts,\n status = 'active',\n } = options;\n\n // Check if this is a transition from draft to active\n const currentPost = await this.db('posts')\n .select('status', 'published')\n .where('id', '=', id)\n .first();\n\n const shouldSetPublished =\n currentPost &&\n currentPost.status === 'draft' &&\n status === 'active' &&\n !currentPost.published;\n\n const query = this.db('posts').where('posts.id', '=', id);\n const rows = await query.update({\n title,\n content,\n headerImage,\n author,\n url,\n updatedBy: setUpdatedBy ? user_ref : undefined,\n updated: setUpdatedBy ? new Date() : undefined,\n status,\n published: shouldSetPublished ? new Date() : undefined,\n });\n\n if (!rows) {\n return null;\n }\n\n await Promise.all([\n this.addTags(id, tags, true),\n this.addEntities(id, entities, true),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n id,\n headerImage,\n );\n\n return await this.getPost(user_ref, id, false, opts);\n }\n\n async deletePost(id: number, permanently?: boolean): Promise<boolean> {\n if (permanently) {\n const rows = await this.db('posts').where('id', '=', id).delete();\n return rows > 0;\n }\n const rows = await this.db('posts').where('id', '=', id).update({\n status: 'deleted',\n });\n return rows > 0;\n }\n\n async votePost(\n user_ref: string,\n postId: number,\n score: number,\n ): Promise<boolean> {\n await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n await this.db\n .insert({\n author: user_ref,\n postId,\n score,\n timestamp: new Date(),\n })\n .into('post_votes');\n\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n return true;\n }\n\n async getPostVote(\n user_ref: string,\n postId: number,\n ): Promise<RawPostVoteEntity | undefined> {\n return await this.db<RawPostVoteEntity>('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .first();\n }\n\n async deletePostVote(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n if (rows > 0) {\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n }\n return rows > 0;\n }\n\n async favoritePost(user_ref: string, postId: number): Promise<boolean> {\n await this.db\n .insert({\n user: user_ref,\n postId,\n })\n .into('user_favorite');\n await this.db('posts').where('id', postId).increment('favoritesCount', 1);\n return true;\n }\n\n async unfavoritePost(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('user_favorite')\n .where('user', user_ref)\n .where('postId', postId)\n .delete();\n if (rows > 0) {\n await this.db('posts').where('id', postId).decrement('favoritesCount', 1);\n }\n return true;\n }\n\n async getUsersWhoFavoritedPost(postId: number): Promise<string[]> {\n const users = await this.db('user_favorite')\n .where('postId', postId)\n .select('user');\n return users.map(user => user.user);\n }\n\n private async mapPostEntities(\n rows: RawPostEntity[],\n user_ref: string,\n options?: PostOptions,\n ): Promise<Post[]> {\n if (rows.length === 0) {\n return [];\n }\n\n const postIds = rows.map(r => r.id);\n const {\n includeTags = true,\n includeAnswers = true,\n includeVotes = true,\n includeEntities = true,\n includeComments = true,\n includeAttachments = true,\n includeExperts = true,\n includeCollections = true,\n includeHealth = false,\n } = options ?? {};\n\n const [\n tags,\n votes,\n entities,\n comments,\n attachments,\n experts,\n answers,\n collections,\n ] = await Promise.all([\n includeTags\n ? this.tagsStore.getRelatedTags(\n postIds,\n 'post_tags',\n 'postId',\n options?.tagsFilter,\n )\n : undefined,\n includeVotes\n ? this.db<RawPostVoteEntity>('post_votes')\n .whereIn('postId', postIds)\n .select()\n : undefined,\n includeEntities\n ? this.entitiesStore.getRelatedEntities(\n postIds,\n 'post_entities',\n 'postId',\n )\n : undefined,\n includeComments\n ? this.commentsStore.getPostComments(postIds, options?.commentsFilter)\n : undefined,\n includeAttachments\n ? this.attachmentsStore.getAttachments(postIds, 'postId')\n : undefined,\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('post_tags', 'tag_experts.tagId', 'post_tags.tagId')\n .whereIn('post_tags.postId', postIds)\n .select('post_tags.postId', 'tag_experts.entityRef')\n : undefined,\n includeAnswers && this.answersStore\n ? this.answersStore.getPostAnswers(postIds, user_ref, {\n ...options,\n includePost: false,\n filter: options?.answersFilter,\n })\n : undefined,\n includeCollections\n ? this.db('collection_posts')\n .whereIn('postId', postIds)\n .select('postId', 'collectionId')\n : undefined,\n ]);\n\n const tagsMap = tags ?? new Map<number, string[]>();\n\n const votesMap = new Map<number, RawPostVoteEntity[]>();\n votes?.forEach((v: RawPostVoteEntity) => {\n const ps = votesMap.get(v.postId) || [];\n ps.push(v);\n votesMap.set(v.postId, ps);\n });\n\n const entitiesMap = entities ?? new Map<number, string[]>();\n\n const commentsMap = new Map<number, QetaComment[]>();\n (comments as unknown as (QetaComment & { postId: number })[])?.forEach(\n c => {\n const ps = commentsMap.get(c.postId) || [];\n ps.push(c);\n commentsMap.set(c.postId, ps);\n },\n );\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.postId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.postId, ps);\n });\n\n const answersMap = new Map<number, Answer[]>();\n answers?.forEach((a: Answer) => {\n const ps = answersMap.get(a.postId) || [];\n ps.push(a);\n answersMap.set(a.postId, ps);\n });\n\n const collectionsMap = new Map<number, number[]>();\n (collections as any)?.forEach((c: any) => {\n const cs = collectionsMap.get(c.postId) || [];\n cs.push(c.collectionId);\n collectionsMap.set(c.postId, cs);\n });\n\n return rows.map(val => {\n const postVotes = votesMap.get(val.id) || [];\n const post: Post = {\n id: val.id,\n author:\n val.anonymous && val.author !== user_ref ? 'anonymous' : val.author,\n own: val.author === user_ref,\n title: val.title,\n content: val.content,\n created: val.created as Date,\n updated: val.updated as Date,\n updatedBy: val.updatedBy,\n status: val.status as PostStatus,\n score: this.mapToInteger(val.score),\n views: this.mapToInteger(val.views),\n answersCount: this.mapToInteger(val.answersCount),\n correctAnswer: this.mapToBoolean(val.correctAnswers),\n commentsCount: this.mapToInteger(val.commentsCount),\n favorite: this.mapToInteger(val.favorite) > 0,\n tags: tagsMap.get(val.id),\n answers: answersMap.get(val.id),\n votes: postVotes.map(v => ({\n author: v.author,\n score: v.score,\n timestamp: v.timestamp,\n })),\n entities: entitiesMap.get(val.id),\n trend: this.mapToInteger(val.trend),\n comments: commentsMap.get(val.id),\n ownVote: postVotes.find(v => v.author === user_ref)?.score,\n anonymous: val.anonymous,\n type: val.type,\n headerImage: val.headerImage,\n url: val.url ?? undefined,\n images: attachmentsMap.get(val.id),\n experts: expertsMap.get(val.id),\n published: val.published ? (val.published as Date) : undefined,\n collectionIds: collectionsMap.get(val.id),\n };\n\n if (includeHealth || options?.reviewNeeded) {\n const reviewThreshold =\n options?.reviewThresholdMs || 180 * 24 * 60 * 60 * 1000;\n const lastInteraction = val.last_interaction\n ? new Date(val.last_interaction)\n : new Date(val.updated || val.created);\n const now = Date.now();\n const diff = now - lastInteraction.getTime();\n\n let score = 100;\n if (reviewThreshold > 0) {\n score = Math.max(\n 0,\n Math.min(100, Math.floor(100 - (diff / reviewThreshold) * 25)),\n );\n }\n if (val.status === 'obsolete') {\n score = 0;\n }\n post.healthScore = score;\n\n if (reviewThreshold > 0 && val.status !== 'obsolete') {\n post.needsReview = diff >= reviewThreshold;\n }\n }\n\n return post;\n });\n }\n\n private getPostsBaseQuery(user: string, opts?: PostsQuery) {\n const q = this.db<RawPostEntity>('posts')\n .leftJoin('user_favorite', function joinUserFavorite() {\n this.on('posts.id', '=', 'user_favorite.postId').andOnVal(\n 'user_favorite.user',\n '=',\n user,\n );\n })\n .select(\n 'posts.*',\n this.db.raw(\n `CASE WHEN user_favorite.${\n this.db.client.config.client === 'pg' ? '\"postId\"' : 'postId'\n } IS NOT NULL THEN 1 ELSE 0 END as favorite`,\n ),\n );\n\n if (opts?.favorite) {\n q.whereNotNull('user_favorite.postId');\n }\n\n return q;\n }\n\n private async recordPostView(\n postId: number,\n user_ref: string,\n ): Promise<void> {\n await this.db\n .insert({\n author: user_ref,\n postId,\n timestamp: new Date(),\n })\n .into('post_views');\n\n await this.db('posts').where('id', postId).increment('views', 1);\n }\n\n private async addTags(\n id: number,\n tagsInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_tags',\n columnName: string = 'postId',\n ) {\n const tags = filterTags(tagsInput);\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n if (!tags || tags.length === 0) {\n return;\n }\n const existingTags = await this.db('tags')\n .whereIn('tag', tags)\n .returning('id')\n .select();\n const newTags = tags.filter(t => !existingTags.some(e => e.tag === t));\n const allTags: Record<string, string> = {\n ...TAGS,\n ...(await this.tagDatabase?.getTags()),\n };\n\n const tagIds = (\n await Promise.all(\n [...new Set(newTags)].map(async tag => {\n const trimmed = tag.trim();\n const description = trimmed in allTags ? allTags[trimmed] : undefined;\n\n return this.db\n .insert({ tag: trimmed, description })\n .into('tags')\n .returning('id')\n .onConflict('tag')\n .ignore();\n }),\n )\n )\n .flat()\n .map(tag => tag.id)\n .concat(existingTags.map(t => t.id));\n\n await Promise.all(\n tagIds.map(async tagId => {\n await this.db\n .insert({ [columnName]: id, tagId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n\n private async addEntities(\n id: number,\n entitiesInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_entities',\n columnName: string = 'postId',\n ) {\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n const regex = /\\w+:\\w+\\/\\w+/;\n const entities =\n entitiesInput\n ?.filter(t => regex.test(t))\n .map(t => t.toLowerCase())\n .filter(t => t.length > 0) ?? [];\n\n if (!entities || entities.length === 0) {\n return;\n }\n\n const existingEntities = await this.db('entities')\n .whereIn('entity_ref', entities)\n .returning('id')\n .select();\n const newEntities = entities.filter(\n t => !existingEntities.some(e => e.entity_ref === t),\n );\n\n const entityIds = (\n await Promise.all(\n [...new Set(newEntities)].map(async entityRef =>\n this.db\n .insert({ entity_ref: entityRef })\n .into('entities')\n .returning('id')\n .onConflict('entity_ref')\n .ignore(),\n ),\n )\n )\n .flat()\n .map(entity => entity.id)\n .concat(existingEntities.map(c => c.id));\n\n await Promise.all(\n entityIds.map(async entityId => {\n await this.db\n .insert({ [columnName]: id, entityId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n}\n"],"names":["BaseStore","filterTags","removeStopwords","eng","rows","TAGS"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PostsStore.cjs.js","sources":["../../../src/database/stores/PostsStore.ts"],"sourcesContent":["import {\n AIResponse,\n Answer,\n Comment as QetaComment,\n filterTags,\n Post,\n PostReview,\n PostsQuery,\n PostStatus,\n PostType,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { MaybePost, PostOptions, Posts } from '../QetaStore';\nimport { QetaFilters } from '../../service/util';\nimport { Knex } from 'knex';\nimport { AnswersStore } from './AnswersStore';\nimport { CommentsStore } from './CommentsStore';\nimport { CollectionsStore } from './CollectionsStore';\nimport { TagsStore } from './TagsStore';\nimport { EntitiesStore } from './EntitiesStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport { TAGS } from '../../tagDb';\nimport { BaseStore } from './BaseStore';\nimport { TagDatabase } from '@drodil/backstage-plugin-qeta-node';\n\nimport { eng, removeStopwords } from 'stopword';\n\nexport interface RawPostEntity {\n id: number;\n author: string;\n title: string;\n content: string;\n status: string;\n created: Date | string;\n updated: Date | string;\n updatedBy: string;\n score: number | string;\n views: number | string;\n answersCount: number | string;\n correctAnswers: number | string;\n commentsCount: number | string;\n favorite: number | string;\n trend: number | string;\n anonymous: boolean;\n type: 'question' | 'article' | 'link';\n headerImage: string;\n url: string | null;\n published: Date | string | null;\n obsolete: number | string | boolean;\n last_interaction?: Date | string;\n}\n\nexport interface RawPostVoteEntity {\n postId: number;\n author: string;\n score: number;\n timestamp: Date;\n}\n\nexport interface RawPostAIAnswer {\n id: number;\n answer: string;\n created: Date;\n}\n\nexport class PostsStore extends BaseStore {\n private answersStore?: AnswersStore;\n private collectionsStore?: CollectionsStore;\n\n constructor(\n protected readonly db: Knex,\n private readonly commentsStore: CommentsStore,\n private readonly tagsStore: TagsStore,\n private readonly entitiesStore: EntitiesStore,\n private readonly attachmentsStore: AttachmentsStore,\n private readonly tagDatabase?: TagDatabase,\n ) {\n super(db);\n }\n\n setAnswersStore(answersStore: AnswersStore) {\n this.answersStore = answersStore;\n }\n\n setCollectionsStore(collectionsStore: CollectionsStore) {\n this.collectionsStore = collectionsStore;\n }\n\n async getAIAnswer(postId: number): Promise<AIResponse | null> {\n const row = await this.db('post_ai_answers')\n .where('postId', postId)\n .first();\n if (!row) {\n return null;\n }\n return {\n answer: row.answer,\n created: row.created,\n };\n }\n\n async saveAIAnswer(postId: number, response: AIResponse): Promise<void> {\n await this.db\n .insert({\n postId,\n answer: response.answer,\n created: response.created,\n })\n .into('post_ai_answers')\n .onConflict('postId')\n .merge();\n }\n\n async deleteAIAnswer(postId: number): Promise<boolean> {\n const deleted = await this.db('post_ai_answers')\n .where('postId', postId)\n .del();\n return deleted > 0;\n }\n\n async reviewPost(\n user_ref: string,\n postId: number,\n status: 'valid' | 'obsolete',\n comment?: string,\n ): Promise<MaybePost> {\n await this.db('post_reviews').insert({\n post_id: postId,\n reviewer: user_ref,\n status,\n comment,\n created: new Date(),\n });\n\n if (status === 'obsolete') {\n await this.db('posts').where('id', postId).update({ status: 'obsolete' });\n } else {\n await this.db('posts').where('id', postId).update({ status: 'active' });\n }\n\n return this.getPost(user_ref, postId, false, {\n includeHealth: true,\n reviewThresholdMs: 15552000000, // 180 days default\n });\n }\n\n async getPostReviews(postId: number): Promise<PostReview[]> {\n const rows = await this.db('post_reviews')\n .where('post_id', postId)\n .orderBy('created', 'desc')\n .select('*');\n\n return rows.map(row => ({\n id: row.id,\n postId: row.post_id,\n reviewer: row.reviewer,\n status: row.status,\n comment: row.comment,\n created: new Date(row.created),\n }));\n }\n\n async getPosts(\n user_ref: string,\n options: PostsQuery,\n filters?: PermissionCriteria<QetaFilters>,\n opts?: PostOptions,\n ): Promise<Posts> {\n const {\n includeTotal = true,\n includeDraftFilter = true,\n includeHealth = false,\n } = opts ?? {};\n const query = this.getPostsBaseQuery(user_ref, options);\n if (options.type) {\n query.where('posts.type', options.type);\n }\n\n if (options.obsolete !== undefined) {\n if (options.obsolete) {\n query.where('posts.status', 'obsolete');\n } else {\n query.where(q => {\n q.whereNot('posts.status', 'obsolete');\n });\n }\n }\n\n if (options.fromDate && options.toDate) {\n query.whereBetween('posts.created', [\n `${options.fromDate} 00:00:00.000+00`,\n `${options.toDate} 23:59:59.999+00`,\n ]);\n } else if (options.fromDate) {\n query.where('posts.created', '>=', `${options.fromDate} 00:00:00.000+00`);\n } else if (options.toDate) {\n query.where('posts.created', '<=', `${options.toDate} 23:59:59.999+00`);\n }\n\n if (options.author) {\n if (Array.isArray(options.author)) {\n query.whereIn('posts.author', options.author);\n } else {\n query.where('posts.author', '=', options.author);\n }\n }\n\n if (options.excludeAuthors) {\n query.whereNotIn('posts.author', options.excludeAuthors);\n }\n\n if (options.status) {\n if (options.status === 'draft') {\n query.where('posts.author', '=', user_ref);\n }\n query.where('posts.status', '=', options.status);\n } else if (includeDraftFilter) {\n query.where(q => {\n q.whereIn('posts.status', ['active', 'obsolete']).orWhere(q2 => {\n q2.where('posts.status', 'draft').where(\n 'posts.author',\n '=',\n user_ref,\n );\n });\n });\n }\n\n if (filters) {\n this.parseFilter(filters, query, this.db);\n }\n\n if (options.searchQuery) {\n this.applySearchQuery(\n query,\n ['posts.title', 'posts.content'],\n options.searchQuery,\n );\n }\n\n if (options.tags) {\n const tags = filterTags(options.tags);\n if (options.tagsRelation === 'or') {\n query.innerJoin('post_tags', 'posts.id', 'post_tags.postId');\n query.innerJoin('tags', 'post_tags.tagId', 'tags.id');\n query.whereIn('tags.tag', tags);\n } else {\n tags?.forEach((t: string, i: number) => {\n query.innerJoin(`post_tags AS qt${i}`, 'posts.id', `qt${i}.postId`);\n query.innerJoin(`tags AS t${i}`, `qt${i}.tagId`, `t${i}.id`);\n query.where(`t${i}.tag`, '=', t);\n });\n }\n }\n\n if (options.entities) {\n const entityValues = Array.isArray(options.entities)\n ? options.entities\n : [options.entities];\n if (options.entitiesRelation === 'or') {\n query\n .innerJoin('post_entities', 'posts.id', 'post_entities.postId')\n .innerJoin('entities', 'post_entities.entityId', 'entities.id')\n .whereIn('entities.entity_ref', entityValues);\n } else {\n entityValues.forEach((t: string, i: number) => {\n query.innerJoin(\n `post_entities AS pe${i}`,\n 'posts.id',\n `pe${i}.postId`,\n );\n query.innerJoin(`entities AS e${i}`, `pe${i}.entityId`, `e${i}.id`);\n query.where(`e${i}.entity_ref`, '=', t);\n });\n }\n }\n\n if (options.collectionId) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.where('collection_posts.collectionId', options.collectionId);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (opts?.collectionIds) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.whereIn('collection_posts.collectionId', opts.collectionIds);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (options.orderBy === 'rank') {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.select('collection_posts.rank');\n }\n if (options.orderBy === 'rank') {\n if (this.db.client.config.client === 'pg') {\n query.groupBy(\n 'posts.id',\n 'collection_posts.rank',\n this.db.raw('user_favorite.\"postId\"'),\n );\n } else {\n query.groupBy(\n 'posts.id',\n 'collection_posts.rank',\n 'user_favorite.postId',\n );\n }\n }\n\n if (options.noAnswers) {\n query.where('answersCount', 0);\n }\n\n if (options.hasAnswers) {\n query.where('answersCount', '>', 0);\n }\n\n if (options.noCorrectAnswer) {\n query.where('correctAnswers', 0);\n }\n\n if (options.noVotes) {\n query.where('score', 0);\n }\n\n if (options.favorite) {\n query.where('user_favorite.user', '=', user_ref);\n query.whereNotNull('user_favorite.postId');\n }\n\n if (options.includeTrend || options.orderBy === 'trend') {\n query.select(\n this.db.raw(\n `(\n posts.score * 200 + \n posts.\"answersCount\" * 100 +\n posts.\"favoritesCount\" * 50 +\n posts.views * 10 +\n posts.\"commentsCount\" * 30\n ) / \n POWER(\n EXTRACT(EPOCH FROM (now() - posts.created)) / 172800 + 1,\n 1.5\n ) as trend`,\n ),\n );\n }\n\n if (includeHealth || options.reviewNeeded) {\n const func = this.db.client.config.client === 'pg' ? 'GREATEST' : 'MAX';\n const lastInteractionQuery = `${func}(\n posts.created,\n COALESCE((SELECT MAX(created) FROM answers WHERE answers.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM comments WHERE comments.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(ac.created) FROM answers a JOIN comments ac ON ac.\"answerId\" = a.id WHERE a.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM post_reviews WHERE post_reviews.post_id = posts.id), posts.created)\n )`;\n\n query.select(this.db.raw(`${lastInteractionQuery} as last_interaction`));\n\n const reviewThresholdMs = opts?.reviewThresholdMs || 0;\n if (options.reviewNeeded && reviewThresholdMs > 0) {\n const thresholdDate = new Date(Date.now() - reviewThresholdMs);\n const thresholdParam = thresholdDate.toISOString();\n query.whereRaw(`${lastInteractionQuery} < ?`, [thresholdParam]);\n }\n if (options.reviewNeeded) {\n query.whereNotIn('posts.status', ['deleted', 'obsolete']);\n }\n }\n\n if (options.ids) {\n query.whereIn('posts.id', options.ids);\n }\n\n const totalQuery = query.clone();\n\n if (options.random) {\n query.orderByRaw('RANDOM()');\n } else if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n } else {\n query.orderBy('created', 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n includeTotal\n ? this.db(totalQuery.as('totalQuery')).count('* as CNT').first()\n : undefined,\n ]);\n const rows = results[0] as RawPostEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n posts: await this.mapPostEntities(rows, user_ref, {\n ...opts,\n includeAnswers: options.includeAnswers ?? opts?.includeAnswers,\n includeVotes: options.includeVotes ?? opts?.includeVotes,\n includeEntities: options.includeEntities ?? opts?.includeEntities,\n includeAttachments:\n options.includeAttachments ?? opts?.includeAttachments,\n includeExperts: options.includeExperts ?? opts?.includeExperts,\n includeHealth: options.includeHealth ?? opts?.includeHealth,\n }),\n total,\n };\n }\n\n async suggestPosts(\n user_ref: string,\n title: string,\n content: string,\n tags?: string[],\n entities?: string[],\n filters?: PermissionCriteria<QetaFilters>,\n opts?: PostOptions,\n ): Promise<Posts> {\n const titleWords = removeStopwords(title.split(/\\s+/g), eng).join(' ');\n const contentWords = removeStopwords(content.split(/\\s+/g), eng).join(' ');\n\n const [titlePosts, contentPosts, tagPosts, entityPosts] = await Promise.all(\n [\n titleWords && titleWords.length > 0\n ? this.getPosts(\n user_ref,\n {\n searchQuery: titleWords,\n limit: 5,\n type: 'question',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n contentWords && contentWords.length > 0\n ? this.getPosts(\n user_ref,\n {\n searchQuery: contentWords,\n limit: 5,\n type: 'question',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n tags && tags.length > 0\n ? this.getPosts(\n user_ref,\n {\n limit: 5,\n type: 'question',\n tags: tags,\n tagsRelation: 'or',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n entities && entities.length > 0\n ? this.getPosts(\n user_ref,\n {\n limit: 5,\n type: 'question',\n entities: entities,\n entitiesRelation: 'or',\n status: 'active',\n excludeAuthors: [user_ref],\n },\n filters,\n opts,\n )\n : Promise.resolve({ posts: [], total: 0 }),\n ],\n );\n\n const allPosts = [\n ...titlePosts.posts,\n ...contentPosts.posts,\n ...tagPosts.posts,\n ...entityPosts.posts,\n ];\n\n const uniquePosts = Array.from(new Set(allPosts.map(p => p.id)))\n .map(id => allPosts.find(p => p.id === id))\n .filter((p): p is Post => p !== undefined);\n return { posts: uniquePosts.slice(0, 5), total: uniquePosts.length };\n }\n\n async getPost(\n user_ref: string,\n id: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const query = this.getPostsBaseQuery(user_ref).where('posts.id', '=', id);\n\n if (options?.includeHealth) {\n const func = this.db.client.config.client === 'pg' ? 'GREATEST' : 'MAX';\n const lastInteractionQuery = `${func}(\n posts.created,\n COALESCE((SELECT MAX(created) FROM answers WHERE answers.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM comments WHERE comments.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(ac.created) FROM answers a JOIN comments ac ON ac.\"answerId\" = a.id WHERE a.\"postId\" = posts.id), posts.created),\n COALESCE((SELECT MAX(created) FROM post_reviews WHERE post_reviews.post_id = posts.id), posts.created)\n )`;\n query.select(this.db.raw(`${lastInteractionQuery} as last_interaction`));\n }\n\n const rows = await query;\n\n if (!rows || rows.length === 0) {\n return null;\n }\n const post = rows[0] as unknown as RawPostEntity;\n\n if (recordView && post.status === 'active') {\n this.recordPostView(id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async getPostByAnswerId(\n user_ref: string,\n answerId: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const rows = await this.getPostsBaseQuery(user_ref)\n .join('answers', 'posts.id', 'answers.postId')\n .where('answers.id', '=', answerId)\n .select('posts.*');\n if (!rows || rows.length === 0) {\n return null;\n }\n if (recordView) {\n this.recordPostView(rows[0].id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async createPost(options: {\n user_ref: string;\n title: string;\n content: string;\n created: Date;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n anonymous?: boolean;\n type?: PostType;\n headerImage?: string;\n url?: string;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<Post> {\n const {\n user_ref,\n title,\n content,\n author,\n created,\n tags,\n entities,\n images,\n anonymous,\n type = 'question',\n headerImage,\n url,\n opts,\n status = 'active',\n } = options;\n const posts = await this.db\n .insert(\n {\n author: author ?? user_ref,\n title,\n content,\n created,\n anonymous: anonymous ?? false,\n type: type ?? 'question',\n headerImage,\n url,\n status,\n published: status === 'active' ? created : null,\n },\n ['id'],\n )\n .into('posts')\n .returning([\n 'id',\n 'author',\n 'title',\n 'content',\n 'created',\n 'anonymous',\n 'type',\n 'status',\n 'url',\n ]);\n\n await Promise.all([\n this.addTags(posts[0].id, tags),\n this.addEntities(posts[0].id, entities),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n posts[0].id,\n headerImage,\n );\n\n await this.collectionsStore?.syncPostToCollections(posts[0].id);\n\n return (await this.mapPostEntities([posts[0]], user_ref, opts))[0];\n }\n\n async updatePost(options: {\n id: number;\n user_ref: string;\n title?: string;\n content?: string;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n headerImage?: string;\n url?: string;\n setUpdatedBy?: boolean;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<MaybePost> {\n const {\n id,\n user_ref,\n title,\n content,\n author,\n tags,\n entities,\n images,\n headerImage,\n url,\n setUpdatedBy = true,\n opts,\n status = 'active',\n } = options;\n\n // Check if this is a transition from draft to active\n const currentPost = await this.db('posts')\n .select('status', 'published')\n .where('id', '=', id)\n .first();\n\n const shouldSetPublished =\n currentPost &&\n currentPost.status === 'draft' &&\n status === 'active' &&\n !currentPost.published;\n\n const query = this.db('posts').where('posts.id', '=', id);\n const rows = await query.update({\n title,\n content,\n headerImage,\n author,\n url,\n updatedBy: setUpdatedBy ? user_ref : undefined,\n updated: setUpdatedBy ? new Date() : undefined,\n status,\n published: shouldSetPublished ? new Date() : undefined,\n });\n\n if (!rows) {\n return null;\n }\n\n await Promise.all([\n this.addTags(id, tags, true),\n this.addEntities(id, entities, true),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n id,\n headerImage,\n );\n\n await this.collectionsStore?.syncPostToCollections(id);\n\n return await this.getPost(user_ref, id, false, opts);\n }\n\n async deletePost(id: number, permanently?: boolean): Promise<boolean> {\n if (permanently) {\n const rows = await this.db('posts').where('id', '=', id).delete();\n return rows > 0;\n }\n const rows = await this.db('posts').where('id', '=', id).update({\n status: 'deleted',\n });\n return rows > 0;\n }\n\n async votePost(\n user_ref: string,\n postId: number,\n score: number,\n ): Promise<boolean> {\n await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n await this.db\n .insert({\n author: user_ref,\n postId,\n score,\n timestamp: new Date(),\n })\n .into('post_votes');\n\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n return true;\n }\n\n async getPostVote(\n user_ref: string,\n postId: number,\n ): Promise<RawPostVoteEntity | undefined> {\n return await this.db<RawPostVoteEntity>('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .first();\n }\n\n async deletePostVote(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n if (rows > 0) {\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n }\n return rows > 0;\n }\n\n async favoritePost(user_ref: string, postId: number): Promise<boolean> {\n await this.db\n .insert({\n user: user_ref,\n postId,\n })\n .into('user_favorite');\n await this.db('posts').where('id', postId).increment('favoritesCount', 1);\n return true;\n }\n\n async unfavoritePost(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('user_favorite')\n .where('user', user_ref)\n .where('postId', postId)\n .delete();\n if (rows > 0) {\n await this.db('posts').where('id', postId).decrement('favoritesCount', 1);\n }\n return true;\n }\n\n async getUsersWhoFavoritedPost(postId: number): Promise<string[]> {\n const users = await this.db('user_favorite')\n .where('postId', postId)\n .select('user');\n return users.map(user => user.user);\n }\n\n private async mapPostEntities(\n rows: RawPostEntity[],\n user_ref: string,\n options?: PostOptions,\n ): Promise<Post[]> {\n if (rows.length === 0) {\n return [];\n }\n\n const postIds = rows.map(r => r.id);\n const {\n includeTags = true,\n includeAnswers = true,\n includeVotes = true,\n includeEntities = true,\n includeComments = true,\n includeAttachments = true,\n includeExperts = true,\n includeCollections = true,\n includeHealth = false,\n } = options ?? {};\n\n const [\n tags,\n votes,\n entities,\n comments,\n attachments,\n experts,\n answers,\n collections,\n ] = await Promise.all([\n includeTags\n ? this.tagsStore.getRelatedTags(\n postIds,\n 'post_tags',\n 'postId',\n options?.tagsFilter,\n )\n : undefined,\n includeVotes\n ? this.db<RawPostVoteEntity>('post_votes')\n .whereIn('postId', postIds)\n .select()\n : undefined,\n includeEntities\n ? this.entitiesStore.getRelatedEntities(\n postIds,\n 'post_entities',\n 'postId',\n )\n : undefined,\n includeComments\n ? this.commentsStore.getPostComments(postIds, options?.commentsFilter)\n : undefined,\n includeAttachments\n ? this.attachmentsStore.getAttachments(postIds, 'postId')\n : undefined,\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('post_tags', 'tag_experts.tagId', 'post_tags.tagId')\n .whereIn('post_tags.postId', postIds)\n .select('post_tags.postId', 'tag_experts.entityRef')\n : undefined,\n includeAnswers && this.answersStore\n ? this.answersStore.getPostAnswers(postIds, user_ref, {\n ...options,\n includePost: false,\n filter: options?.answersFilter,\n })\n : undefined,\n includeCollections\n ? this.db('collection_posts')\n .whereIn('postId', postIds)\n .select('postId', 'collectionId')\n : undefined,\n ]);\n\n const tagsMap = tags ?? new Map<number, string[]>();\n\n const votesMap = new Map<number, RawPostVoteEntity[]>();\n votes?.forEach((v: RawPostVoteEntity) => {\n const ps = votesMap.get(v.postId) || [];\n ps.push(v);\n votesMap.set(v.postId, ps);\n });\n\n const entitiesMap = entities ?? new Map<number, string[]>();\n\n const commentsMap = new Map<number, QetaComment[]>();\n (comments as unknown as (QetaComment & { postId: number })[])?.forEach(\n c => {\n const ps = commentsMap.get(c.postId) || [];\n ps.push(c);\n commentsMap.set(c.postId, ps);\n },\n );\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.postId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.postId, ps);\n });\n\n const answersMap = new Map<number, Answer[]>();\n answers?.forEach((a: Answer) => {\n const ps = answersMap.get(a.postId) || [];\n ps.push(a);\n answersMap.set(a.postId, ps);\n });\n\n const collectionsMap = new Map<number, number[]>();\n (collections as any)?.forEach((c: any) => {\n const cs = collectionsMap.get(c.postId) || [];\n cs.push(c.collectionId);\n collectionsMap.set(c.postId, cs);\n });\n\n return rows.map(val => {\n const postVotes = votesMap.get(val.id) || [];\n const post: Post = {\n id: val.id,\n author:\n val.anonymous && val.author !== user_ref ? 'anonymous' : val.author,\n own: val.author === user_ref,\n title: val.title,\n content: val.content,\n created: val.created as Date,\n updated: val.updated as Date,\n updatedBy: val.updatedBy,\n status: val.status as PostStatus,\n score: this.mapToInteger(val.score),\n views: this.mapToInteger(val.views),\n answersCount: this.mapToInteger(val.answersCount),\n correctAnswer: this.mapToBoolean(val.correctAnswers),\n commentsCount: this.mapToInteger(val.commentsCount),\n favorite: this.mapToInteger(val.favorite) > 0,\n tags: tagsMap.get(val.id),\n answers: answersMap.get(val.id),\n votes: postVotes.map(v => ({\n author: v.author,\n score: v.score,\n timestamp: v.timestamp,\n })),\n entities: entitiesMap.get(val.id),\n trend: this.mapToInteger(val.trend),\n comments: commentsMap.get(val.id),\n ownVote: postVotes.find(v => v.author === user_ref)?.score,\n anonymous: val.anonymous,\n type: val.type,\n headerImage: val.headerImage,\n url: val.url ?? undefined,\n images: attachmentsMap.get(val.id),\n experts: expertsMap.get(val.id),\n published: val.published ? (val.published as Date) : undefined,\n collectionIds: collectionsMap.get(val.id),\n };\n\n if (includeHealth || options?.reviewNeeded) {\n const reviewThreshold =\n options?.reviewThresholdMs || 180 * 24 * 60 * 60 * 1000;\n const lastInteraction = val.last_interaction\n ? new Date(val.last_interaction)\n : new Date(val.updated || val.created);\n const now = Date.now();\n const diff = now - lastInteraction.getTime();\n\n let score = 100;\n if (reviewThreshold > 0) {\n score = Math.max(\n 0,\n Math.min(100, Math.floor(100 - (diff / reviewThreshold) * 25)),\n );\n }\n if (val.status === 'obsolete') {\n score = 0;\n }\n post.healthScore = score;\n\n if (reviewThreshold > 0 && val.status !== 'obsolete') {\n post.needsReview = diff >= reviewThreshold;\n }\n }\n\n return post;\n });\n }\n\n private getPostsBaseQuery(user: string, opts?: PostsQuery) {\n const q = this.db<RawPostEntity>('posts')\n .leftJoin('user_favorite', function joinUserFavorite() {\n this.on('posts.id', '=', 'user_favorite.postId').andOnVal(\n 'user_favorite.user',\n '=',\n user,\n );\n })\n .select(\n 'posts.*',\n this.db.raw(\n `CASE WHEN user_favorite.${\n this.db.client.config.client === 'pg' ? '\"postId\"' : 'postId'\n } IS NOT NULL THEN 1 ELSE 0 END as favorite`,\n ),\n );\n\n if (opts?.favorite) {\n q.whereNotNull('user_favorite.postId');\n }\n\n return q;\n }\n\n private async recordPostView(\n postId: number,\n user_ref: string,\n ): Promise<void> {\n await this.db\n .insert({\n author: user_ref,\n postId,\n timestamp: new Date(),\n })\n .into('post_views');\n\n await this.db('posts').where('id', postId).increment('views', 1);\n }\n\n private async addTags(\n id: number,\n tagsInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_tags',\n columnName: string = 'postId',\n ) {\n const tags = filterTags(tagsInput);\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n if (!tags || tags.length === 0) {\n return;\n }\n const existingTags = await this.db('tags')\n .whereIn('tag', tags)\n .returning('id')\n .select();\n const newTags = tags.filter(t => !existingTags.some(e => e.tag === t));\n const allTags: Record<string, string> = {\n ...TAGS,\n ...(await this.tagDatabase?.getTags()),\n };\n\n const tagIds = (\n await Promise.all(\n [...new Set(newTags)].map(async tag => {\n const trimmed = tag.trim();\n const description = trimmed in allTags ? allTags[trimmed] : undefined;\n\n return this.db\n .insert({ tag: trimmed, description })\n .into('tags')\n .returning('id')\n .onConflict('tag')\n .ignore();\n }),\n )\n )\n .flat()\n .map(tag => tag.id)\n .concat(existingTags.map(t => t.id));\n\n await Promise.all(\n tagIds.map(async tagId => {\n await this.db\n .insert({ [columnName]: id, tagId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n\n private async addEntities(\n id: number,\n entitiesInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_entities',\n columnName: string = 'postId',\n ) {\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n const regex = /\\w+:\\w+\\/\\w+/;\n const entities =\n entitiesInput\n ?.filter(t => regex.test(t))\n .map(t => t.toLowerCase())\n .filter(t => t.length > 0) ?? [];\n\n if (!entities || entities.length === 0) {\n return;\n }\n\n const existingEntities = await this.db('entities')\n .whereIn('entity_ref', entities)\n .returning('id')\n .select();\n const newEntities = entities.filter(\n t => !existingEntities.some(e => e.entity_ref === t),\n );\n\n const entityIds = (\n await Promise.all(\n [...new Set(newEntities)].map(async entityRef =>\n this.db\n .insert({ entity_ref: entityRef })\n .into('entities')\n .returning('id')\n .onConflict('entity_ref')\n .ignore(),\n ),\n )\n )\n .flat()\n .map(entity => entity.id)\n .concat(existingEntities.map(c => c.id));\n\n await Promise.all(\n entityIds.map(async entityId => {\n await this.db\n .insert({ [columnName]: id, entityId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n}\n"],"names":["BaseStore","filterTags","removeStopwords","eng","rows","TAGS"],"mappings":"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"}
|
|
@@ -119,6 +119,9 @@ const collectionsRoutes = (router, options) => {
|
|
|
119
119
|
created,
|
|
120
120
|
images: request.body.images,
|
|
121
121
|
headerImage: request.body.headerImage,
|
|
122
|
+
tags: request.body.tags,
|
|
123
|
+
entities: request.body.entities,
|
|
124
|
+
users: request.body.users,
|
|
122
125
|
opts: { includePosts: false }
|
|
123
126
|
});
|
|
124
127
|
if (!collection) {
|
|
@@ -202,6 +205,9 @@ const collectionsRoutes = (router, options) => {
|
|
|
202
205
|
description: request.body.description,
|
|
203
206
|
images: request.body.images,
|
|
204
207
|
headerImage: request.body.headerImage,
|
|
208
|
+
tags: request.body.tags,
|
|
209
|
+
entities: request.body.entities,
|
|
210
|
+
users: request.body.users,
|
|
205
211
|
opts: { postFilters, tagFilters, filters }
|
|
206
212
|
});
|
|
207
213
|
if (!collection) {
|