@drodil/backstage-plugin-qeta-backend 3.55.1 → 3.55.3
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/service/routes/helpers.cjs.js +9 -5
- package/dist/service/routes/helpers.cjs.js.map +1 -1
- package/dist/service/routes/posts.cjs.js +3 -0
- package/dist/service/routes/posts.cjs.js.map +1 -1
- package/dist/service/types.cjs.js +5 -0
- package/dist/service/types.cjs.js.map +1 -1
- package/package.json +7 -6
|
@@ -207,7 +207,7 @@ const helperRoutes = (router, options) => {
|
|
|
207
207
|
},
|
|
208
208
|
{ token }
|
|
209
209
|
);
|
|
210
|
-
const entityTags = entityResponse.items.flatMap((e) => e?.metadata?.tags).filter((t) => !!t).map((tag) => tag.toLocaleLowerCase()).filter(backstagePluginQetaCommon.filterTags)
|
|
210
|
+
const entityTags = entityResponse.items.flatMap((e) => e?.metadata?.tags).filter((t) => !!t).map((tag) => tag.toLocaleLowerCase()).filter(backstagePluginQetaCommon.filterTags);
|
|
211
211
|
suggestedTags.push(...entityTags);
|
|
212
212
|
} catch (_error) {
|
|
213
213
|
}
|
|
@@ -216,7 +216,7 @@ const helperRoutes = (router, options) => {
|
|
|
216
216
|
if (aiHandler?.suggestTags) {
|
|
217
217
|
const { tags } = await aiHandler.suggestTags(title, content);
|
|
218
218
|
suggestedTags.unshift(...tags);
|
|
219
|
-
return [...new Set(suggestedTags)].
|
|
219
|
+
return [...new Set(suggestedTags)].map((tag) => tag.toLocaleLowerCase()).filter(backstagePluginQetaCommon.filterTags);
|
|
220
220
|
}
|
|
221
221
|
} catch (_error) {
|
|
222
222
|
}
|
|
@@ -242,7 +242,7 @@ const helperRoutes = (router, options) => {
|
|
|
242
242
|
suggestedTags.push(tag.tag);
|
|
243
243
|
}
|
|
244
244
|
});
|
|
245
|
-
return [...new Set(suggestedTags)].filter(backstagePluginQetaCommon.filterTags)
|
|
245
|
+
return [...new Set(suggestedTags)].filter(backstagePluginQetaCommon.filterTags);
|
|
246
246
|
};
|
|
247
247
|
router.post("/tags/suggest", async (request, response) => {
|
|
248
248
|
const validateRequestBody = ajv.compile(types.DraftQuestionSchema);
|
|
@@ -259,7 +259,9 @@ const helperRoutes = (router, options) => {
|
|
|
259
259
|
);
|
|
260
260
|
const allTags = request.body.tags ? [.../* @__PURE__ */ new Set([...request.body.tags, ...suggestedTags])] : suggestedTags;
|
|
261
261
|
const uniqueTags = [...new Set(allTags)];
|
|
262
|
-
|
|
262
|
+
const limit = request.body.limit && request.body.limit > 0 ? request.body.limit : uniqueTags.length;
|
|
263
|
+
const randomizedTags = uniqueTags.sort(() => Math.random() - 0.5);
|
|
264
|
+
response.json({ tags: randomizedTags.slice(0, limit) });
|
|
263
265
|
} catch (error) {
|
|
264
266
|
logger.error(`Failed to generate tag suggestions: ${error}`);
|
|
265
267
|
response.status(500).json({ error: "Failed to generate tag suggestions" });
|
|
@@ -474,7 +476,9 @@ const helperRoutes = (router, options) => {
|
|
|
474
476
|
const ref = catalogModel.stringifyEntityRef(entity);
|
|
475
477
|
return !request.body.entities?.includes(ref);
|
|
476
478
|
});
|
|
477
|
-
|
|
479
|
+
const limit = request.body.limit && request.body.limit > 0 ? request.body.limit : notSetEntities.length;
|
|
480
|
+
const randomizedEntities = notSetEntities.sort(() => Math.random() - 0.5);
|
|
481
|
+
response.json({ entities: randomizedEntities.slice(0, limit) });
|
|
478
482
|
} catch (error) {
|
|
479
483
|
logger.error(`Failed to generate entity suggestions: ${error}`);
|
|
480
484
|
response.status(500).json({ error: "Failed to generate entity suggestions" });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs.js","sources":["../../../src/service/routes/helpers.ts"],"sourcesContent":["import { Request, Router } from 'express';\nimport {\n DeleteMetadataSchema,\n DraftQuestionSchema,\n EntitiesQuerySchema,\n RouteOptions,\n TagsQuerySchema,\n UsersQuerySchema,\n} from '../types';\nimport { mapAdditionalFields } from '../util';\nimport { getCachedData } from './routeUtil';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n filterTags,\n getSupportedEntityKinds,\n isValidTag,\n qetaCreateTagPermission,\n qetaDeleteTagPermission,\n qetaEditTagPermission,\n qetaReadAnswerPermission,\n qetaReadCollectionPermission,\n qetaReadCommentPermission,\n qetaReadPostPermission,\n qetaReadTagPermission,\n TagsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport { eng, removeStopwords } from 'stopword';\nimport { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const helperRoutes = (router: Router, options: RouteOptions) => {\n const {\n database,\n catalog,\n auth,\n config,\n httpAuth,\n auditor,\n logger,\n permissionMgr,\n aiHandler,\n } = options;\n\n const supportedKinds = getSupportedEntityKinds(config);\n\n const validateEntityRef = (entityRef: string, kind?: string) => {\n try {\n const valid = parseEntityRef(entityRef);\n if (\n kind &&\n valid.kind.toLocaleLowerCase('en-US') !==\n kind.toLocaleLowerCase('en-US')\n ) {\n throw new Error(`Expected kind: ${kind}`);\n }\n } catch (error) {\n throw new Error(`Invalid entityRef: ${entityRef}`);\n }\n };\n\n router.get('/users', async (request, response) => {\n const validateQuery = ajv.compile(UsersQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const users = await catalog.queryEntities(\n {\n filter: { kind: 'User' },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = users.items\n .map(user => {\n try {\n return stringifyEntityRef(user);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const users = await database.getUsers({ entityRefs, ...request.query });\n response.json(users);\n });\n\n router.get('/users/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const key = `qeta:followed:users:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const users = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getFollowedUsers(username),\n options.logger,\n );\n response.json(users);\n });\n\n router.put('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.followUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'follow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n await options.cache?.delete(`qeta:followed:users:${username}`);\n\n response.status(204).send();\n });\n\n router.delete('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'unfollow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n await options.cache?.delete(`qeta:followed:users:${username}`);\n\n response.status(204).send();\n });\n\n // GET /tags\n router.get('/tags', async (request, response) => {\n const validateQuery = ajv.compile(TagsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n\n const opts = request.query as TagsQuery;\n const tags = await database.getTags(opts, filter);\n\n await mapAdditionalFields(request, tags.tags, options, {\n checkRights: opts.checkAccess ?? false,\n });\n\n response.json(tags);\n });\n\n router.get('/tags/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n const key = `qeta:followed:tags:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const tags = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getUserTags(username, filter),\n options.logger,\n );\n\n response.json(tags);\n });\n\n router.put('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.followTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'follow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n\n await options.cache?.delete(`qeta:followed:tags:${username}`);\n\n response.status(204).send();\n });\n\n router.delete('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'unfollow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n await options.cache?.delete(`qeta:followed:tags:${username}`);\n response.status(204).send();\n });\n\n const getSuggestedTags = async (\n request: Request,\n title: string,\n content: string,\n entities?: string[],\n ) => {\n const suggestedTags: string[] = [];\n if (entities && entities.length > 0) {\n try {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entityResponse = await catalog.getEntitiesByRefs(\n {\n entityRefs: entities,\n fields: ['metadata.tags'],\n filter: {\n 'metadata.tags': CATALOG_FILTER_EXISTS,\n },\n },\n { token },\n );\n const entityTags = entityResponse.items\n .flatMap(e => e?.metadata?.tags)\n .filter((t): t is string => !!t)\n .map(tag => tag.toLocaleLowerCase())\n .filter(filterTags)\n .slice(0, 5);\n suggestedTags.push(...entityTags);\n } catch (_error) {\n // Just ignore\n }\n }\n\n try {\n if (aiHandler?.suggestTags) {\n const { tags } = await aiHandler.suggestTags(title, content);\n suggestedTags.unshift(...tags);\n return [...new Set(suggestedTags)]\n .filter(filterTags)\n .map(tag => tag.toLocaleLowerCase())\n .slice(0, 10);\n }\n } catch (_error) {\n // NOOP: Fallback to database suggestions\n }\n\n const cleanWords = (words: string[]): string[] =>\n removeStopwords(words, [...eng]);\n\n const { tags: existingTags } = await database.getTags();\n\n const titleLower = title.toLocaleLowerCase();\n const titleWords = cleanWords(\n titleLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n const contentLower = content.toLocaleLowerCase();\n const contentWords = cleanWords(\n contentLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n\n existingTags.forEach(tag => {\n if (\n titleLower.includes(tag.tag.toLocaleLowerCase()) ||\n contentLower.includes(tag.tag.toLocaleLowerCase())\n ) {\n suggestedTags.push(tag.tag);\n return;\n }\n\n const descriptionWords = cleanWords(\n tag.description?.toLocaleLowerCase().split(/\\s+/) || [],\n );\n\n if (\n titleWords.some(word => descriptionWords.includes(word)) ||\n contentWords.some(word => descriptionWords.includes(word))\n ) {\n suggestedTags.push(tag.tag);\n }\n });\n\n return [...new Set(suggestedTags)].filter(filterTags).slice(0, 10);\n };\n\n router.post('/tags/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n const uniqueTags = [...new Set(allTags)];\n\n response.json({ tags: uniqueTags });\n } catch (error) {\n logger.error(`Failed to generate tag suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate tag suggestions' });\n }\n });\n\n router.get('/tags/:tag', async (request, response) => {\n const tag = await database.getTag(request.params.tag);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'read-tag',\n severityLevel: 'low',\n request,\n meta: { tagId: tag.id, tag: tag.tag },\n });\n response.json(tag);\n });\n\n router.post('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n if (Number.isNaN(tagId)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n const resp = await database.updateTag(tagId, description, experts);\n await mapAdditionalFields(request, resp ? [resp] : [], options);\n auditor?.createEvent({\n eventId: 'update-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...resp,\n tagId: tag.id,\n },\n });\n\n response.json(resp);\n });\n\n router.put('/tags', async (request, response) => {\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreateTagPermission }],\n { throwOnDeny: true },\n );\n\n const existing = await database.getTag(request.body.tag);\n if (existing) {\n response.status(409).send({ errors: 'Tag already exists', type: 'body' });\n return;\n }\n\n if (!isValidTag(request.body.tag)) {\n response.status(400).send({ errors: 'Invalid tag', type: 'body' });\n return;\n }\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n\n const tag = await database.createTag(\n request.body.tag,\n description,\n experts,\n );\n if (!tag) {\n response.sendStatus(500);\n return;\n }\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'create-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...tag,\n tagId: tag.id,\n },\n });\n response.status(201).json(tag);\n });\n\n router.delete('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (Number.isNaN(tagId) || !validateRequestBody(request.body)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteTagPermission, resource: tag! }],\n { throwOnDeny: true },\n );\n const deleted = await database.deleteTag(tagId);\n\n if (deleted) {\n auditor?.createEvent({\n eventId: 'delete-tag',\n severityLevel: 'medium',\n request,\n meta: {\n tagId,\n reason: request.body.reason,\n },\n });\n }\n // Response\n response.sendStatus(deleted ? 204 : 404);\n });\n\n router.get('/entities', async (request, response) => {\n const validateQuery = ajv.compile(EntitiesQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n kind: supportedKinds,\n },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'metadata.description',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = entities.items\n .map(entity => {\n try {\n return stringifyEntityRef(entity);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const entities = await database.getEntities({\n entityRefs,\n ...request.query,\n });\n response.json(entities);\n });\n\n router.post('/entities/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n if (!allTags.length) {\n response.json({ entities: [] });\n return;\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n 'metadata.tags': allTags,\n kind: supportedKinds,\n },\n },\n { token },\n );\n\n const notSetEntities = entities.items.filter(entity => {\n const ref = stringifyEntityRef(entity);\n return !request.body.entities?.includes(ref);\n });\n\n response.json({ entities: notSetEntities });\n } catch (error) {\n logger.error(`Failed to generate entity suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate entity suggestions' });\n }\n });\n\n router.get('/entities/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const key = `qeta:followed:entities:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const entities = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getUserEntities(username),\n options.logger,\n );\n response.json(entities);\n });\n\n router.get('/entities/links', async (request, response) => {\n const credentials = await httpAuth.credentials(request, {\n allow: ['service'],\n });\n if (!credentials) {\n response.sendStatus(401);\n return;\n }\n\n const links = await database.getEntityLinks();\n response.json(links);\n });\n\n router.put('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.followEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'follow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n await options.cache?.delete(`qeta:followed:entities:${username}`);\n response.status(204).send();\n });\n\n router.delete('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'unfollow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n await options.cache?.delete(`qeta:followed:entities:${username}`);\n response.status(204).send();\n });\n\n router.get('/entities/:entityRef(*)', async (request, response) => {\n validateEntityRef(request.params.entityRef);\n const entity = await database.getEntity(request.params.entityRef);\n if (entity === null) {\n response.sendStatus(404);\n return;\n }\n auditor?.createEvent({\n eventId: 'read-entity',\n severityLevel: 'low',\n request,\n meta: { entityRef: request.params.entityRef },\n });\n response.json(entity);\n });\n\n // GET /timeline\n router.get(`/timeline`, async (request, response) => {\n const username = await permissionMgr.getUsername(request, true);\n const limit = request.query.limit\n ? Number.parseInt(request.query.limit as string, 10)\n : 10;\n const offset = request.query.offset\n ? Number.parseInt(request.query.offset as string, 10)\n : 0;\n const includeTotal = request.query.includeTotal === 'true';\n\n const [filter, commentsFilter, answersFilter, collectionsFilter] =\n await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCommentPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadAnswerPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n ]);\n\n const timeline = await database.getTimeline(\n username,\n { limit, offset, includeTotal },\n {\n posts: filter,\n answers: answersFilter,\n comments: commentsFilter,\n collections: collectionsFilter,\n },\n );\n response.json(timeline);\n });\n};\n"],"names":["Ajv","addFormats","getSupportedEntityKinds","parseEntityRef","UsersQuerySchema","users","stringifyEntityRef","getCachedData","TagsQuerySchema","qetaReadTagPermission","mapAdditionalFields","CATALOG_FILTER_EXISTS","filterTags","removeStopwords","eng","DraftQuestionSchema","qetaEditTagPermission","qetaCreateTagPermission","isValidTag","DeleteMetadataSchema","qetaDeleteTagPermission","EntitiesQuerySchema","entities","qetaReadPostPermission","qetaReadCommentPermission","qetaReadAnswerPermission","qetaReadCollectionPermission"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers.cjs.js","sources":["../../../src/service/routes/helpers.ts"],"sourcesContent":["import { Request, Router } from 'express';\nimport {\n DeleteMetadataSchema,\n DraftQuestionSchema,\n EntitiesQuerySchema,\n RouteOptions,\n TagsQuerySchema,\n UsersQuerySchema,\n} from '../types';\nimport { mapAdditionalFields } from '../util';\nimport { getCachedData } from './routeUtil';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n filterTags,\n getSupportedEntityKinds,\n isValidTag,\n qetaCreateTagPermission,\n qetaDeleteTagPermission,\n qetaEditTagPermission,\n qetaReadAnswerPermission,\n qetaReadCollectionPermission,\n qetaReadCommentPermission,\n qetaReadPostPermission,\n qetaReadTagPermission,\n TagsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport { eng, removeStopwords } from 'stopword';\nimport { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const helperRoutes = (router: Router, options: RouteOptions) => {\n const {\n database,\n catalog,\n auth,\n config,\n httpAuth,\n auditor,\n logger,\n permissionMgr,\n aiHandler,\n } = options;\n\n const supportedKinds = getSupportedEntityKinds(config);\n\n const validateEntityRef = (entityRef: string, kind?: string) => {\n try {\n const valid = parseEntityRef(entityRef);\n if (\n kind &&\n valid.kind.toLocaleLowerCase('en-US') !==\n kind.toLocaleLowerCase('en-US')\n ) {\n throw new Error(`Expected kind: ${kind}`);\n }\n } catch (error) {\n throw new Error(`Invalid entityRef: ${entityRef}`);\n }\n };\n\n router.get('/users', async (request, response) => {\n const validateQuery = ajv.compile(UsersQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const users = await catalog.queryEntities(\n {\n filter: { kind: 'User' },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = users.items\n .map(user => {\n try {\n return stringifyEntityRef(user);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const users = await database.getUsers({ entityRefs, ...request.query });\n response.json(users);\n });\n\n router.get('/users/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const key = `qeta:followed:users:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const users = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getFollowedUsers(username),\n options.logger,\n );\n response.json(users);\n });\n\n router.put('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.followUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'follow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n await options.cache?.delete(`qeta:followed:users:${username}`);\n\n response.status(204).send();\n });\n\n router.delete('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'unfollow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n await options.cache?.delete(`qeta:followed:users:${username}`);\n\n response.status(204).send();\n });\n\n // GET /tags\n router.get('/tags', async (request, response) => {\n const validateQuery = ajv.compile(TagsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n\n const opts = request.query as TagsQuery;\n const tags = await database.getTags(opts, filter);\n\n await mapAdditionalFields(request, tags.tags, options, {\n checkRights: opts.checkAccess ?? false,\n });\n\n response.json(tags);\n });\n\n router.get('/tags/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n const key = `qeta:followed:tags:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const tags = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getUserTags(username, filter),\n options.logger,\n );\n\n response.json(tags);\n });\n\n router.put('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.followTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'follow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n\n await options.cache?.delete(`qeta:followed:tags:${username}`);\n\n response.status(204).send();\n });\n\n router.delete('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'unfollow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n await options.cache?.delete(`qeta:followed:tags:${username}`);\n response.status(204).send();\n });\n\n const getSuggestedTags = async (\n request: Request,\n title: string,\n content: string,\n entities?: string[],\n ) => {\n const suggestedTags: string[] = [];\n if (entities && entities.length > 0) {\n try {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entityResponse = await catalog.getEntitiesByRefs(\n {\n entityRefs: entities,\n fields: ['metadata.tags'],\n filter: {\n 'metadata.tags': CATALOG_FILTER_EXISTS,\n },\n },\n { token },\n );\n const entityTags = entityResponse.items\n .flatMap(e => e?.metadata?.tags)\n .filter((t): t is string => !!t)\n .map(tag => tag.toLocaleLowerCase())\n .filter(filterTags);\n suggestedTags.push(...entityTags);\n } catch (_error) {\n // Just ignore\n }\n }\n\n try {\n if (aiHandler?.suggestTags) {\n const { tags } = await aiHandler.suggestTags(title, content);\n suggestedTags.unshift(...tags);\n return [...new Set(suggestedTags)]\n .map(tag => tag.toLocaleLowerCase())\n .filter(filterTags);\n }\n } catch (_error) {\n // NOOP: Fallback to database suggestions\n }\n\n const cleanWords = (words: string[]): string[] =>\n removeStopwords(words, [...eng]);\n\n const { tags: existingTags } = await database.getTags();\n\n const titleLower = title.toLocaleLowerCase();\n const titleWords = cleanWords(\n titleLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n const contentLower = content.toLocaleLowerCase();\n const contentWords = cleanWords(\n contentLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n\n existingTags.forEach(tag => {\n if (\n titleLower.includes(tag.tag.toLocaleLowerCase()) ||\n contentLower.includes(tag.tag.toLocaleLowerCase())\n ) {\n suggestedTags.push(tag.tag);\n return;\n }\n\n const descriptionWords = cleanWords(\n tag.description?.toLocaleLowerCase().split(/\\s+/) || [],\n );\n\n if (\n titleWords.some(word => descriptionWords.includes(word)) ||\n contentWords.some(word => descriptionWords.includes(word))\n ) {\n suggestedTags.push(tag.tag);\n }\n });\n\n return [...new Set(suggestedTags)].filter(filterTags);\n };\n\n router.post('/tags/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n const uniqueTags = [...new Set(allTags)];\n\n const limit =\n request.body.limit && request.body.limit > 0\n ? request.body.limit\n : uniqueTags.length;\n\n const randomizedTags = uniqueTags.sort(() => Math.random() - 0.5);\n response.json({ tags: randomizedTags.slice(0, limit) });\n } catch (error) {\n logger.error(`Failed to generate tag suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate tag suggestions' });\n }\n });\n\n router.get('/tags/:tag', async (request, response) => {\n const tag = await database.getTag(request.params.tag);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'read-tag',\n severityLevel: 'low',\n request,\n meta: { tagId: tag.id, tag: tag.tag },\n });\n response.json(tag);\n });\n\n router.post('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n if (Number.isNaN(tagId)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n const resp = await database.updateTag(tagId, description, experts);\n await mapAdditionalFields(request, resp ? [resp] : [], options);\n auditor?.createEvent({\n eventId: 'update-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...resp,\n tagId: tag.id,\n },\n });\n\n response.json(resp);\n });\n\n router.put('/tags', async (request, response) => {\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreateTagPermission }],\n { throwOnDeny: true },\n );\n\n const existing = await database.getTag(request.body.tag);\n if (existing) {\n response.status(409).send({ errors: 'Tag already exists', type: 'body' });\n return;\n }\n\n if (!isValidTag(request.body.tag)) {\n response.status(400).send({ errors: 'Invalid tag', type: 'body' });\n return;\n }\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n\n const tag = await database.createTag(\n request.body.tag,\n description,\n experts,\n );\n if (!tag) {\n response.sendStatus(500);\n return;\n }\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'create-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...tag,\n tagId: tag.id,\n },\n });\n response.status(201).json(tag);\n });\n\n router.delete('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (Number.isNaN(tagId) || !validateRequestBody(request.body)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteTagPermission, resource: tag! }],\n { throwOnDeny: true },\n );\n const deleted = await database.deleteTag(tagId);\n\n if (deleted) {\n auditor?.createEvent({\n eventId: 'delete-tag',\n severityLevel: 'medium',\n request,\n meta: {\n tagId,\n reason: request.body.reason,\n },\n });\n }\n // Response\n response.sendStatus(deleted ? 204 : 404);\n });\n\n router.get('/entities', async (request, response) => {\n const validateQuery = ajv.compile(EntitiesQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n kind: supportedKinds,\n },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'metadata.description',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = entities.items\n .map(entity => {\n try {\n return stringifyEntityRef(entity);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const entities = await database.getEntities({\n entityRefs,\n ...request.query,\n });\n response.json(entities);\n });\n\n router.post('/entities/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n if (!allTags.length) {\n response.json({ entities: [] });\n return;\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n 'metadata.tags': allTags,\n kind: supportedKinds,\n },\n },\n { token },\n );\n\n const notSetEntities = entities.items.filter(entity => {\n const ref = stringifyEntityRef(entity);\n return !request.body.entities?.includes(ref);\n });\n\n const limit =\n request.body.limit && request.body.limit > 0\n ? request.body.limit\n : notSetEntities.length;\n\n const randomizedEntities = notSetEntities.sort(() => Math.random() - 0.5);\n response.json({ entities: randomizedEntities.slice(0, limit) });\n } catch (error) {\n logger.error(`Failed to generate entity suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate entity suggestions' });\n }\n });\n\n router.get('/entities/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const key = `qeta:followed:entities:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const entities = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getUserEntities(username),\n options.logger,\n );\n response.json(entities);\n });\n\n router.get('/entities/links', async (request, response) => {\n const credentials = await httpAuth.credentials(request, {\n allow: ['service'],\n });\n if (!credentials) {\n response.sendStatus(401);\n return;\n }\n\n const links = await database.getEntityLinks();\n response.json(links);\n });\n\n router.put('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.followEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'follow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n await options.cache?.delete(`qeta:followed:entities:${username}`);\n response.status(204).send();\n });\n\n router.delete('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'unfollow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n await options.cache?.delete(`qeta:followed:entities:${username}`);\n response.status(204).send();\n });\n\n router.get('/entities/:entityRef(*)', async (request, response) => {\n validateEntityRef(request.params.entityRef);\n const entity = await database.getEntity(request.params.entityRef);\n if (entity === null) {\n response.sendStatus(404);\n return;\n }\n auditor?.createEvent({\n eventId: 'read-entity',\n severityLevel: 'low',\n request,\n meta: { entityRef: request.params.entityRef },\n });\n response.json(entity);\n });\n\n // GET /timeline\n router.get(`/timeline`, async (request, response) => {\n const username = await permissionMgr.getUsername(request, true);\n const limit = request.query.limit\n ? Number.parseInt(request.query.limit as string, 10)\n : 10;\n const offset = request.query.offset\n ? Number.parseInt(request.query.offset as string, 10)\n : 0;\n const includeTotal = request.query.includeTotal === 'true';\n\n const [filter, commentsFilter, answersFilter, collectionsFilter] =\n await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCommentPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadAnswerPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n ]);\n\n const timeline = await database.getTimeline(\n username,\n { limit, offset, includeTotal },\n {\n posts: filter,\n answers: answersFilter,\n comments: commentsFilter,\n collections: collectionsFilter,\n },\n );\n response.json(timeline);\n });\n};\n"],"names":["Ajv","addFormats","getSupportedEntityKinds","parseEntityRef","UsersQuerySchema","users","stringifyEntityRef","getCachedData","TagsQuerySchema","qetaReadTagPermission","mapAdditionalFields","CATALOG_FILTER_EXISTS","filterTags","removeStopwords","eng","DraftQuestionSchema","qetaEditTagPermission","qetaCreateTagPermission","isValidTag","DeleteMetadataSchema","qetaDeleteTagPermission","EntitiesQuerySchema","entities","qetaReadPostPermission","qetaReadCommentPermission","qetaReadAnswerPermission","qetaReadCollectionPermission"],"mappings":"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"}
|
|
@@ -91,6 +91,9 @@ const postsRoutes = (router, options) => {
|
|
|
91
91
|
response.status(404).send({ errors: "Post not found", type: "query" });
|
|
92
92
|
return null;
|
|
93
93
|
}
|
|
94
|
+
if (recordView === true) {
|
|
95
|
+
util.signalPostStats(options.signals, { ...post, views: post.views + 1 });
|
|
96
|
+
}
|
|
94
97
|
return {
|
|
95
98
|
post,
|
|
96
99
|
username,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posts.cjs.js","sources":["../../../src/service/routes/posts.ts"],"sourcesContent":["import { getCreated, mapAdditionalFields } from '../util';\nimport { durationToMilliseconds, HumanDuration } from '@backstage/types';\nimport Ajv from 'ajv';\nimport { Request, Router } from 'express';\nimport {\n findEntityMentions,\n PostsQuery,\n qetaCreateCommentPermission,\n qetaCreatePostPermission,\n qetaCreatePostReviewPermission,\n qetaDeleteCommentPermission,\n qetaDeletePostPermission,\n qetaEditCommentPermission,\n qetaEditPostPermission,\n qetaReadAnswerPermission,\n qetaReadCommentPermission,\n qetaReadPostPermission,\n qetaReadPostReviewPermission,\n qetaReadTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport addFormats from 'ajv-formats';\nimport {\n CommentSchema,\n DeleteMetadataSchema,\n PostQuerySchema,\n PostReviewBodySchema,\n PostSchema,\n PostsQuerySchema,\n RouteOptions,\n URLMetadataSchema,\n} from '../types';\nimport { Response } from 'express-serve-static-core';\nimport {\n entityToJsonObject,\n extractMetadata,\n signalPostStats,\n validateDateRange,\n wrapAsync,\n} from './util';\nimport { getCachedData, getEntities, getTags } from './routeUtil';\nimport { PostOptions } from '../../database/QetaStore';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const postsRoutes = (router: Router, options: RouteOptions) => {\n const {\n database,\n events,\n config,\n cache,\n signals,\n notificationMgr,\n auditor,\n permissionMgr,\n } = options;\n\n const postsOlderThan = config.getOptional<HumanDuration>(\n 'qeta.contentHealth.postsOlderThan',\n ) ?? { months: 6 };\n const reviewThresholdMs = durationToMilliseconds(postsOlderThan);\n\n const getPostFilters = async (request: Request, opts: PostOptions) => {\n return await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n opts.includeTags\n ? permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n })\n : undefined,\n opts.includeComments\n ? permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCommentPermission,\n { allowServicePrincipal: true },\n )\n : undefined,\n opts.includeAnswers\n ? permissionMgr.getAuthorizeConditions(\n request,\n qetaReadAnswerPermission,\n { allowServicePrincipal: true },\n )\n : undefined,\n ]);\n };\n\n const getPostAndCheckStatus = async (\n request: Request,\n response: Response,\n recordView?: boolean,\n allowServiceToken?: boolean,\n ) => {\n const username = await permissionMgr.getUsername(\n request,\n allowServiceToken,\n );\n const postId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(postId)) {\n response.status(400).send({ errors: 'Invalid post id', type: 'body' });\n return null;\n }\n\n const [tagsFilter, commentsFilter, answersFilter] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: allowServiceToken,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadCommentPermission, {\n allowServicePrincipal: allowServiceToken,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadAnswerPermission, {\n allowServicePrincipal: allowServiceToken,\n }),\n ]);\n\n const post = await database.getPost(username, postId, recordView, {\n tagsFilter,\n commentsFilter,\n answersFilter,\n includeHealth: true,\n reviewThresholdMs,\n });\n\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return null;\n }\n\n if (\n post.status === 'deleted' &&\n !(await permissionMgr.isModerator(request))\n ) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return null;\n }\n\n if (post.status === 'draft' && post.author !== username) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return null;\n }\n\n return {\n post,\n username,\n postId,\n tagsFilter,\n commentsFilter,\n answersFilter,\n };\n };\n\n // GET /posts\n router.get(`/posts`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(PostsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const validDate = validateDateRange(\n request.query.fromDate as string,\n request.query.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const opts = request.query as PostsQuery;\n\n if (opts.reviewNeeded) {\n opts.obsolete = false;\n opts.includeHealth = true;\n }\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, opts);\n\n if (\n opts.status === 'deleted' &&\n !(await permissionMgr.isModerator(request))\n ) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n\n // Act\n const posts = await database.getPosts(username, opts, filter, {\n tagsFilter,\n commentsFilter,\n answersFilter,\n includeAnswers: false,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n includeHealth: opts.includeHealth,\n reviewThresholdMs,\n reviewNeeded: opts.reviewNeeded,\n });\n\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n response.json(posts);\n });\n\n router.post(`/posts/query`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(PostsQuerySchema);\n if (!validateQuery(request.body)) {\n response.status(400).send({ errors: validateQuery.errors, type: 'body' });\n return;\n }\n\n const validDate = validateDateRange(\n request.body.fromDate as string,\n request.body.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const opts = request.body;\n\n if (\n opts.status === 'deleted' &&\n !(await permissionMgr.isModerator(request))\n ) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, opts);\n\n if (opts.reviewNeeded) {\n opts.obsolete = false;\n opts.includeHealth = true;\n }\n\n // Act\n const posts = await database.getPosts(username, opts, filter, {\n tagsFilter,\n commentsFilter,\n answersFilter,\n includeAnswers: false,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n includeHealth: opts.includeHealth,\n reviewThresholdMs,\n reviewNeeded: opts.reviewNeeded,\n });\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n response.json(posts);\n });\n\n // POST /posts/suggest\n router.post(`/posts/suggest`, async (request, response) => {\n const username = await permissionMgr.getUsername(request, true);\n if (!request.body.title) {\n response.status(400).send({ errors: 'Title is required', type: 'body' });\n return;\n }\n\n const { title, content, tags, entities } = request.body;\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, {\n includeAnswers: true,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n });\n\n const posts = await database.suggestPosts(\n username,\n title,\n content,\n tags,\n entities,\n filter,\n { tagsFilter, commentsFilter, answersFilter },\n );\n\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: false,\n username,\n });\n response.json(posts);\n });\n\n // GET /posts/list/:type\n router.get(`/posts/list/:type`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(PostsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const optionOverride: PostsQuery = { status: 'active' };\n const type = request.params.type;\n if (type === 'unanswered') {\n optionOverride.random = true;\n optionOverride.noAnswers = true;\n } else if (type === 'incorrect') {\n optionOverride.noCorrectAnswer = true;\n optionOverride.random = true;\n } else if (type === 'hot') {\n optionOverride.includeTrend = true;\n optionOverride.orderBy = 'trend';\n } else if (type === 'own') {\n optionOverride.author = username;\n }\n const opts = { ...request.query, ...optionOverride };\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, opts);\n\n // Act\n const key = `qeta:posts:list:${type}:${username}:${JSON.stringify(opts)}`;\n const ttl = 300 * 1000;\n\n const posts = await getCachedData(\n options.cache,\n key,\n ttl,\n async () => {\n return await database.getPosts(username, opts, filter, {\n includeTotal: false,\n includeAnswers: false,\n includeAttachments: false,\n includeEntities: false,\n includeTags: false,\n includeVotes: false,\n includeExperts: false,\n includeComments: false,\n commentsFilter,\n tagsFilter,\n answersFilter,\n });\n },\n options.logger,\n );\n\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n response.json(posts);\n });\n\n // GET /posts/:id\n router.get(`/posts/:id`, async (request, response) => {\n const validateQuery = ajv.compile(PostQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n const anonymous = request.query.anonymous as undefined | boolean;\n\n const ret = await getPostAndCheckStatus(\n request,\n response,\n anonymous ? !anonymous : true,\n true,\n );\n if (!ret) return;\n const { post, username } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n await mapAdditionalFields(request, [post], options, { username });\n if (!anonymous) {\n signalPostStats(signals, post);\n }\n\n auditor?.createEvent({\n eventId: 'read-post',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(post) },\n });\n\n response.json(post);\n });\n\n // POST /posts/:id/comments\n router.post(`/posts/:id/comments`, async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const { post, username, answersFilter, tagsFilter, commentsFilter } = ret;\n\n const created = await getCreated(request, options);\n const validateRequestBody = ajv.compile(CommentSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .send({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n if (post.status === 'obsolete') {\n response.status(400).send({\n errors: 'Cannot add comments to obsolete posts',\n type: 'body',\n });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaReadPostPermission, resource: post },\n { permission: qetaCreateCommentPermission },\n ],\n { throwOnDeny: true },\n );\n\n const updatedPost = await database.commentPost(\n post.id,\n username,\n request.body.content,\n created,\n { tagsFilter, commentsFilter, answersFilter },\n );\n\n if (updatedPost === null) {\n response\n .status(400)\n .send({ errors: 'Failed to comment post', type: 'body' });\n return;\n }\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n wrapAsync(async () => {\n if (!updatedPost || updatedPost.status !== 'active') {\n return;\n }\n const followingUsers = await Promise.all([\n database.getUsersForTags(updatedPost.tags),\n database.getUsersForEntities(updatedPost.entities),\n database.getFollowingUsers(username),\n database.getUsersWhoFavoritedPost(updatedPost.id),\n ]);\n\n const sent = await notificationMgr.onNewPostComment(\n username,\n updatedPost,\n request.body.content,\n followingUsers.flat(),\n );\n const mentions = findEntityMentions(request.body.content);\n if (mentions.length > 0) {\n await notificationMgr.onMention(\n username,\n updatedPost,\n mentions,\n sent,\n true,\n );\n }\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post: updatedPost,\n comment: request.body.content,\n author: username,\n },\n metadata: { action: 'comment_post' },\n });\n\n auditor?.createEvent({\n eventId: 'comment-post',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(updatedPost),\n comment: request.body.content,\n },\n });\n\n response.status(201).json(updatedPost);\n });\n\n // POST /posts/:id/comments/:commentId\n router.post(`/posts/:id/comments/:commentId`, async (request, response) => {\n // Validation\n // Act\n const postId = Number.parseInt(request.params.id, 10);\n const commentId = Number.parseInt(request.params.commentId, 10);\n if (Number.isNaN(postId) || Number.isNaN(commentId)) {\n response.status(400).send({ errors: 'Invalid id', type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const { post, username, answersFilter, commentsFilter, tagsFilter } = ret;\n\n if (post.status === 'obsolete') {\n response.status(400).send({\n errors: 'Cannot edit comments on obsolete posts',\n type: 'body',\n });\n return;\n }\n\n const comment = await database.getComment(commentId, { postId });\n\n if (!comment) {\n response.status(404).send({ errors: 'Comment not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditCommentPermission, resource: comment }],\n { throwOnDeny: true },\n );\n\n const updatedPost = await database.updatePostComment(\n postId,\n commentId,\n username,\n request.body.content,\n {\n tagsFilter,\n commentsFilter,\n answersFilter,\n },\n );\n\n if (updatedPost === null) {\n response\n .status(400)\n .send({ errors: 'Failed to update post comment', type: 'body' });\n return;\n }\n\n auditor?.createEvent({\n eventId: 'update-comment',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(updatedPost),\n from: entityToJsonObject(comment),\n to: request.body.content,\n },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // DELETE /posts/:id/comments/:commentId\n router.delete(`/posts/:id/comments/:commentId`, async (request, response) => {\n // Validation\n // Act\n const postId = Number.parseInt(request.params.id, 10);\n const commentId = Number.parseInt(request.params.commentId, 10);\n if (Number.isNaN(postId) || Number.isNaN(commentId)) {\n response.status(400).send({ errors: 'Invalid id', type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const { post, username, answersFilter, tagsFilter, commentsFilter } = ret;\n\n if (post.status === 'obsolete') {\n response.status(400).send({\n errors: 'Cannot delete comments on obsolete posts',\n type: 'body',\n });\n return;\n }\n\n const comment = await database.getComment(commentId, { postId });\n\n if (!comment) {\n response.status(404).send({ errors: 'Comment not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteCommentPermission, resource: comment }],\n { throwOnDeny: true },\n );\n\n let updatedPost = null;\n if (comment.status === 'deleted' || request.body?.permanent === true) {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(404)\n .send({ errors: 'Comment not found', type: 'query' });\n return;\n }\n updatedPost = await database.deletePostComment(\n postId,\n commentId,\n username,\n true,\n {\n tagsFilter,\n commentsFilter,\n answersFilter,\n },\n );\n } else {\n updatedPost = await database.deletePostComment(\n postId,\n commentId,\n username,\n false,\n {\n tagsFilter,\n commentsFilter,\n answersFilter,\n },\n );\n }\n\n if (updatedPost === null) {\n response\n .status(400)\n .send({ errors: 'Failed to delete post comment', type: 'body' });\n return;\n }\n\n auditor?.createEvent({\n eventId: 'delete-comment',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(updatedPost),\n comment: entityToJsonObject(comment),\n },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // POST /posts\n router.post(`/posts`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(PostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreatePostPermission }],\n { throwOnDeny: true },\n );\n\n const existingTags = await database.getTags();\n const [tags, entities, username, created] = await Promise.all([\n getTags(request, options, existingTags),\n getEntities(request, config),\n permissionMgr.getUsername(request),\n getCreated(request, options),\n ]);\n\n if (request.body.author && request.body.author !== username) {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n }\n\n // Act\n const post = await database.createPost({\n user_ref: username,\n title: request.body.title,\n content: request.body.content,\n author: request.body.author,\n created,\n tags,\n entities,\n images: request.body.images,\n anonymous: request.body.anonymous || username === 'user:default/guest',\n type: request.body.type,\n headerImage: request.body.headerImage,\n url: request.body.url,\n status: request.body.status || 'active',\n opts: {\n includeComments: false,\n includeVotes: false,\n includeAnswers: false,\n },\n });\n\n if (!post) {\n response.status(400).send({ errors: 'Failed to post', type: 'body' });\n return;\n }\n\n wrapAsync(async () => {\n if (!post || post.status !== 'active') {\n return;\n }\n const followingUsers = await Promise.all([\n database.getUsersForTags(tags),\n database.getUsersForEntities(entities),\n database.getFollowingUsers(username),\n database.getUsersWhoFavoritedPost(post.id),\n ]);\n const sent = await notificationMgr.onNewPost(\n username,\n post,\n followingUsers.flat(),\n );\n const mentions = findEntityMentions(request.body.content);\n if (mentions.length > 0) {\n await notificationMgr.onMention(username, post, mentions, sent);\n }\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'new_post' },\n });\n\n auditor?.createEvent({\n eventId: 'create-post',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(post),\n },\n });\n\n await mapAdditionalFields(request, [post], options, { username });\n\n // Response\n response.status(201).json(post);\n });\n\n // POST /posts/:id\n router.post(`/posts/:id`, async (request, response) => {\n // Validation\n\n const validateRequestBody = ajv.compile(PostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const {\n post: originalPost,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditPostPermission, resource: originalPost }],\n { throwOnDeny: true },\n );\n\n if (request.body.status !== 'active' && originalPost.status === 'active') {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n }\n\n if (\n request.body.author &&\n request.body.author !== username &&\n request.body.author !== originalPost.author\n ) {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n }\n\n const existingTags = await database.getTags();\n const [tags, entities] = await Promise.all([\n getTags(request, options, existingTags),\n getEntities(request, config),\n ]);\n\n // Act\n const post = await database.updatePost({\n id: postId,\n user_ref: username,\n author: request.body.author,\n title: request.body.title,\n content: request.body.content,\n tags,\n entities,\n images: request.body.images,\n headerImage: request.body.headerImage,\n url: request.body.url,\n status: request.body.status || 'active',\n setUpdatedBy: originalPost.status !== 'draft',\n opts: { tagsFilter, commentsFilter, answersFilter },\n });\n\n if (!post) {\n response.sendStatus(401);\n return;\n }\n\n wrapAsync(async () => {\n if (!post || post.status !== 'active') {\n return;\n }\n const newTags = tags.filter(t => !originalPost.tags?.includes(t));\n const newEntities = entities.filter(\n e => !originalPost.entities?.includes(e),\n );\n\n const followingUsers = await Promise.all([\n database.getUsersForTags(newTags),\n database.getUsersForEntities(newEntities),\n ]);\n\n const sent = await notificationMgr.onPostEdit(\n username,\n post,\n followingUsers.flat(),\n );\n const originalMentions = findEntityMentions(originalPost.content);\n const mentions = findEntityMentions(request.body.content);\n const newMentions = mentions.filter(m => !originalMentions.includes(m));\n\n if (newMentions.length > 0) {\n await notificationMgr.onMention(username, post, newMentions, sent);\n }\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'update_post' },\n });\n\n await mapAdditionalFields(request, [post], options, { username });\n\n auditor?.createEvent({\n eventId: 'update-post',\n severityLevel: 'medium',\n request,\n meta: {\n from: entityToJsonObject(originalPost),\n to: entityToJsonObject(post),\n },\n });\n\n // Response\n response.json(post);\n });\n\n // DELETE /posts/:id\n router.delete('/posts/:id', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: 'Invalid data', type: 'body' });\n return;\n }\n\n const { post, username } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeletePostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n let deleted = false;\n if (post.status === 'deleted' || request.body?.permanent === true) {\n if (!(await permissionMgr.isModerator(request))) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n deleted = await database.deletePost(post.id, true);\n } else {\n deleted = await database.deletePost(post.id);\n if (deleted) {\n notificationMgr.onPostDelete(username, post, request.body.reason);\n }\n }\n\n if (deleted) {\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: post.author,\n reason: request.body.reason,\n },\n metadata: { action: 'delete_post' },\n });\n\n auditor?.createEvent({\n eventId: 'delete-post',\n severityLevel: 'medium',\n request,\n meta: { post: entityToJsonObject(post), reason: request.body.reason },\n });\n }\n\n response.sendStatus(deleted ? 204 : 404);\n });\n\n const votePost = async (\n request: Request<any>,\n response: Response,\n score: number,\n ) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n if (post.own) {\n response\n .status(400)\n .send({ errors: 'You cannot vote your own post', type: 'body' });\n return;\n }\n\n const voted = await database.votePost(username, postId, score);\n\n if (!voted) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n const resp = await database.getPost(username, postId, false, {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeTags: false,\n includeEntities: false,\n });\n if (resp === null) {\n response.sendStatus(404);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n resp,\n author: username,\n score,\n },\n metadata: { action: 'vote_post' },\n });\n\n await mapAdditionalFields(request, [resp], options, { username });\n resp.ownVote = score;\n\n auditor?.createEvent({\n eventId: 'vote',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(post), score },\n });\n\n signalPostStats(signals, resp);\n\n // Response\n response.json(resp);\n };\n\n // POST /posts/:id/restore\n router.post('/posts/:id/restore', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n\n if (!(await permissionMgr.isModerator(request))) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n const {\n post: originalPost,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n // Act\n const post = await database.updatePost({\n id: postId,\n status: 'active',\n user_ref: username,\n setUpdatedBy: false,\n opts: { tagsFilter, commentsFilter, answersFilter },\n });\n\n if (!post) {\n response.sendStatus(401);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'restore_post' },\n });\n\n await mapAdditionalFields(request, [post], options, { username });\n\n auditor?.createEvent({\n eventId: 'restore-post',\n severityLevel: 'medium',\n request,\n meta: {\n from: entityToJsonObject(originalPost),\n to: entityToJsonObject(post),\n },\n });\n\n // Response\n response.json(post);\n });\n\n // PUT /posts/:id/click\n router.put('/posts/:id/click', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n const { postId, username } = ret;\n await database.clickPost(username, postId);\n\n const resp = await database.getPost(username, postId, false, {\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeTags: false,\n includeEntities: false,\n });\n\n if (!resp) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n\n signalPostStats(signals, resp);\n response.status(200).send({});\n });\n\n // GET /posts/:id/upvote\n router.get(`/posts/:id/upvote`, async (request, response) => {\n return await votePost(request, response, 1);\n });\n\n // GET /posts/:id/downvote\n router.get(`/posts/:id/downvote`, async (request, response) => {\n return await votePost(request, response, -1);\n });\n\n router.delete('/posts/:id/vote', async (request, response) => {\n // Validation\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n const deleted = await database.deletePostVote(username, postId);\n if (!deleted) {\n response.sendStatus(404);\n return;\n }\n\n const resp = await database.getPost(username, postId, false, {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeTags: false,\n includeEntities: false,\n });\n\n if (resp === null) {\n response.sendStatus(404);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'delete_vote' },\n });\n\n await mapAdditionalFields(request, [resp], options, { username });\n resp.ownVote = undefined;\n\n signalPostStats(signals, resp);\n\n auditor?.createEvent({\n eventId: 'delete-vote',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(post) },\n });\n response.json(resp);\n });\n\n // POST /posts/:id/review\n router.post('/posts/:id/review', async (request, response) => {\n const validateRequestBody = ajv.compile(PostReviewBodySchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const { post, postId } = ret;\n\n const user = await options.permissionMgr.getUsername(request, true);\n\n await options.permissionMgr.authorize(\n request,\n [\n { permission: qetaReadPostPermission, resource: post },\n { permission: qetaCreatePostReviewPermission },\n ],\n { throwOnDeny: true },\n );\n\n const updatedPost = await options.database.reviewPost(\n user,\n postId,\n request.body.status,\n request.body.comment,\n );\n if (!updatedPost) {\n response.sendStatus(404);\n return;\n }\n response.json(updatedPost);\n });\n\n // GET /posts/:id/reviews\n router.get('/posts/:id/reviews', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const { post, postId } = ret;\n\n await options.permissionMgr.authorize(\n request,\n [\n { permission: qetaReadPostPermission, resource: post },\n { permission: qetaReadPostReviewPermission },\n ],\n { throwOnDeny: true },\n );\n\n const reviews = await options.database.getPostReviews(postId);\n response.json(reviews);\n });\n\n // GET /posts/:id/favorite\n router.get(`/posts/:id/favorite`, async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n const favorited = await database.favoritePost(username, postId);\n\n if (!favorited) {\n response.sendStatus(404);\n return;\n }\n\n const updatedPost = await database.getPost(\n username,\n Number.parseInt(request.params.id, 10),\n false,\n {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeEntities: false,\n includeVotes: false,\n includeTags: false,\n includeAttachments: false,\n },\n );\n\n if (!updatedPost) {\n response.sendStatus(404);\n return;\n }\n\n auditor?.createEvent({\n eventId: 'favorite-post',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(updatedPost) },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // GET /posts/:id/unfavorite\n router.get(`/posts/:id/unfavorite`, async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n const unfavorited = await database.unfavoritePost(username, postId);\n\n if (!unfavorited) {\n response.sendStatus(404);\n return;\n }\n\n const updatedPost = await database.getPost(\n username,\n Number.parseInt(request.params.id, 10),\n false,\n {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeEntities: false,\n includeVotes: false,\n includeTags: false,\n includeAttachments: false,\n },\n );\n\n if (!updatedPost) {\n response.sendStatus(404);\n return;\n }\n\n auditor?.createEvent({\n eventId: 'unfavorite-post',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(updatedPost) },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // POST /url\n router.post(`/url`, async (request, response) => {\n const validateQuery = ajv.compile(URLMetadataSchema);\n if (!validateQuery(request.body)) {\n response.status(400).send({ errors: validateQuery.errors, type: 'body' });\n return;\n }\n\n const url = new URL(request.body.url);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n response\n .status(400)\n .send({ errors: 'Invalid URL protocol', type: 'url' });\n return;\n }\n if (url.hostname === 'localhost') {\n response\n .status(400)\n .send({ errors: 'localhost not allowed', type: 'url' });\n return;\n }\n\n const cacheKey = `url:metadata:${url.toString()}`;\n const cached = await cache?.get(cacheKey);\n if (cached) {\n response.json(cached);\n return;\n }\n\n const metadata = await extractMetadata(url, options.logger);\n await cache?.set(cacheKey, metadata, { ttl: { weeks: 2 } });\n response.json(metadata);\n });\n};\n"],"names":["Ajv","addFormats","durationToMilliseconds","qetaReadPostPermission","qetaReadTagPermission","qetaReadCommentPermission","qetaReadAnswerPermission","PostsQuerySchema","validateDateRange","mapAdditionalFields","getCachedData","PostQuerySchema","signalPostStats","entityToJsonObject","getCreated","CommentSchema","qetaCreateCommentPermission","wrapAsync","findEntityMentions","qetaEditCommentPermission","qetaDeleteCommentPermission","PostSchema","qetaCreatePostPermission","getTags","getEntities","qetaEditPostPermission","DeleteMetadataSchema","qetaDeletePostPermission","PostReviewBodySchema","qetaCreatePostReviewPermission","qetaReadPostReviewPermission","URLMetadataSchema","extractMetadata"],"mappings":";;;;;;;;;;;;;;;;AA0CA,MAAM,MAAM,IAAIA,oBAAA,CAAI,EAAE,WAAA,EAAa,SAAS,CAAA;AAC5CC,2BAAA,CAAW,GAAG,CAAA;AAED,MAAA,WAAA,GAAc,CAAC,MAAA,EAAgB,OAA0B,KAAA;AACpE,EAAM,MAAA;AAAA,IACJ,QAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,eAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACE,GAAA,OAAA;AAEJ,EAAA,MAAM,iBAAiB,MAAO,CAAA,WAAA;AAAA,IAC5B;AAAA,GACF,IAAK,EAAE,MAAA,EAAQ,CAAE,EAAA;AACjB,EAAM,MAAA,iBAAA,GAAoBC,6BAAuB,cAAc,CAAA;AAE/D,EAAM,MAAA,cAAA,GAAiB,OAAO,OAAA,EAAkB,IAAsB,KAAA;AACpE,IAAO,OAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,MACvB,aAAA,CAAc,sBAAuB,CAAA,OAAA,EAASC,gDAAwB,EAAA;AAAA,QACpE,qBAAuB,EAAA;AAAA,OACxB,CAAA;AAAA,MACD,IAAK,CAAA,WAAA,GACD,aAAc,CAAA,sBAAA,CAAuB,SAASC,+CAAuB,EAAA;AAAA,QACnE,qBAAuB,EAAA;AAAA,OACxB,CACD,GAAA,KAAA,CAAA;AAAA,MACJ,IAAA,CAAK,kBACD,aAAc,CAAA,sBAAA;AAAA,QACZ,OAAA;AAAA,QACAC,mDAAA;AAAA,QACA,EAAE,uBAAuB,IAAK;AAAA,OAEhC,GAAA,KAAA,CAAA;AAAA,MACJ,IAAA,CAAK,iBACD,aAAc,CAAA,sBAAA;AAAA,QACZ,OAAA;AAAA,QACAC,kDAAA;AAAA,QACA,EAAE,uBAAuB,IAAK;AAAA,OAEhC,GAAA,KAAA;AAAA,KACL,CAAA;AAAA,GACH;AAEA,EAAA,MAAM,qBAAwB,GAAA,OAC5B,OACA,EAAA,QAAA,EACA,YACA,iBACG,KAAA;AACH,IAAM,MAAA,QAAA,GAAW,MAAM,aAAc,CAAA,WAAA;AAAA,MACnC,OAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,SAAS,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,IAAI,EAAE,CAAA;AACpD,IAAI,IAAA,MAAA,CAAO,KAAM,CAAA,MAAM,CAAG,EAAA;AACxB,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,iBAAA,EAAmB,IAAM,EAAA,MAAA,EAAQ,CAAA;AACrE,MAAO,OAAA,IAAA;AAAA;AAGT,IAAA,MAAM,CAAC,UAAY,EAAA,cAAA,EAAgB,aAAa,CAAI,GAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,MACpE,aAAA,CAAc,sBAAuB,CAAA,OAAA,EAASF,+CAAuB,EAAA;AAAA,QACnE,qBAAuB,EAAA;AAAA,OACxB,CAAA;AAAA,MACD,aAAA,CAAc,sBAAuB,CAAA,OAAA,EAASC,mDAA2B,EAAA;AAAA,QACvE,qBAAuB,EAAA;AAAA,OACxB,CAAA;AAAA,MACD,aAAA,CAAc,sBAAuB,CAAA,OAAA,EAASC,kDAA0B,EAAA;AAAA,QACtE,qBAAuB,EAAA;AAAA,OACxB;AAAA,KACF,CAAA;AAED,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,OAAQ,CAAA,QAAA,EAAU,QAAQ,UAAY,EAAA;AAAA,MAChE,UAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,aAAe,EAAA,IAAA;AAAA,MACf;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAO,OAAA,IAAA;AAAA;AAGT,IACE,IAAA,IAAA,CAAK,WAAW,SAChB,IAAA,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CACzC,EAAA;AACA,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAO,OAAA,IAAA;AAAA;AAGT,IAAA,IAAI,IAAK,CAAA,MAAA,KAAW,OAAW,IAAA,IAAA,CAAK,WAAW,QAAU,EAAA;AACvD,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAO,OAAA,IAAA;AAAA;AAGT,IAAO,OAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,MACA,UAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,MAAA,CAAA,EAAU,OAAO,OAAA,EAAS,QAAa,KAAA;AAEhD,IAAA,MAAM,QAAW,GAAA,MAAM,aAAc,CAAA,WAAA,CAAY,SAAS,IAAI,CAAA;AAC9D,IAAM,MAAA,aAAA,GAAgB,GAAI,CAAA,OAAA,CAAQC,wBAAgB,CAAA;AAClD,IAAA,IAAI,CAAC,aAAA,CAAc,OAAQ,CAAA,KAAK,CAAG,EAAA;AACjC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,aAAc,CAAA,MAAA,EAAQ,IAAM,EAAA,OAAA,EAAS,CAAA;AACvD,MAAA;AAAA;AAGF,IAAA,MAAM,SAAY,GAAAC,sBAAA;AAAA,MAChB,QAAQ,KAAM,CAAA,QAAA;AAAA,MACd,QAAQ,KAAM,CAAA;AAAA,KAChB;AACA,IAAI,IAAA,CAAC,WAAW,OAAS,EAAA;AACvB,MAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,SAAS,CAAA;AACnC,MAAA;AAAA;AAGF,IAAA,MAAM,OAAO,OAAQ,CAAA,KAAA;AAErB,IAAA,IAAI,KAAK,YAAc,EAAA;AACrB,MAAA,IAAA,CAAK,QAAW,GAAA,KAAA;AAChB,MAAA,IAAA,CAAK,aAAgB,GAAA,IAAA;AAAA;AAGvB,IAAM,MAAA,CAAC,QAAQ,UAAY,EAAA,cAAA,EAAgB,aAAa,CACtD,GAAA,MAAM,cAAe,CAAA,OAAA,EAAS,IAAI,CAAA;AAEpC,IACE,IAAA,IAAA,CAAK,WAAW,SAChB,IAAA,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CACzC,EAAA;AACA,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAA;AAAA;AAIF,IAAA,MAAM,QAAQ,MAAM,QAAA,CAAS,QAAS,CAAA,QAAA,EAAU,MAAM,MAAQ,EAAA;AAAA,MAC5D,UAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAgB,EAAA,KAAA;AAAA,MAChB,eAAiB,EAAA,KAAA;AAAA,MACjB,kBAAoB,EAAA,KAAA;AAAA,MACpB,cAAgB,EAAA,KAAA;AAAA,MAChB,eAAe,IAAK,CAAA,aAAA;AAAA,MACpB,iBAAA;AAAA,MACA,cAAc,IAAK,CAAA;AAAA,KACpB,CAAA;AAED,IAAA,MAAMC,0BAAoB,CAAA,OAAA,EAAS,KAAM,CAAA,KAAA,EAAO,OAAS,EAAA;AAAA,MACvD,WAAA,EAAa,KAAK,WAAe,IAAA,KAAA;AAAA,MACjC;AAAA,KACD,CAAA;AACD,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,GACpB,CAAA;AAED,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,YAAA,CAAA,EAAgB,OAAO,OAAA,EAAS,QAAa,KAAA;AAEvD,IAAA,MAAM,QAAW,GAAA,MAAM,aAAc,CAAA,WAAA,CAAY,SAAS,IAAI,CAAA;AAC9D,IAAM,MAAA,aAAA,GAAgB,GAAI,CAAA,OAAA,CAAQF,wBAAgB,CAAA;AAClD,IAAA,IAAI,CAAC,aAAA,CAAc,OAAQ,CAAA,IAAI,CAAG,EAAA;AAChC,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA,EAAE,QAAQ,aAAc,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AACxE,MAAA;AAAA;AAGF,IAAA,MAAM,SAAY,GAAAC,sBAAA;AAAA,MAChB,QAAQ,IAAK,CAAA,QAAA;AAAA,MACb,QAAQ,IAAK,CAAA;AAAA,KACf;AACA,IAAI,IAAA,CAAC,WAAW,OAAS,EAAA;AACvB,MAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,SAAS,CAAA;AACnC,MAAA;AAAA;AAGF,IAAA,MAAM,OAAO,OAAQ,CAAA,IAAA;AAErB,IACE,IAAA,IAAA,CAAK,WAAW,SAChB,IAAA,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CACzC,EAAA;AACA,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAA;AAAA;AAGF,IAAM,MAAA,CAAC,QAAQ,UAAY,EAAA,cAAA,EAAgB,aAAa,CACtD,GAAA,MAAM,cAAe,CAAA,OAAA,EAAS,IAAI,CAAA;AAEpC,IAAA,IAAI,KAAK,YAAc,EAAA;AACrB,MAAA,IAAA,CAAK,QAAW,GAAA,KAAA;AAChB,MAAA,IAAA,CAAK,aAAgB,GAAA,IAAA;AAAA;AAIvB,IAAA,MAAM,QAAQ,MAAM,QAAA,CAAS,QAAS,CAAA,QAAA,EAAU,MAAM,MAAQ,EAAA;AAAA,MAC5D,UAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAgB,EAAA,KAAA;AAAA,MAChB,eAAiB,EAAA,KAAA;AAAA,MACjB,kBAAoB,EAAA,KAAA;AAAA,MACpB,cAAgB,EAAA,KAAA;AAAA,MAChB,eAAe,IAAK,CAAA,aAAA;AAAA,MACpB,iBAAA;AAAA,MACA,cAAc,IAAK,CAAA;AAAA,KACpB,CAAA;AACD,IAAA,MAAMC,0BAAoB,CAAA,OAAA,EAAS,KAAM,CAAA,KAAA,EAAO,OAAS,EAAA;AAAA,MACvD,WAAA,EAAa,KAAK,WAAe,IAAA,KAAA;AAAA,MACjC;AAAA,KACD,CAAA;AACD,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,GACpB,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,cAAA,CAAA,EAAkB,OAAO,OAAA,EAAS,QAAa,KAAA;AACzD,IAAA,MAAM,QAAW,GAAA,MAAM,aAAc,CAAA,WAAA,CAAY,SAAS,IAAI,CAAA;AAC9D,IAAI,IAAA,CAAC,OAAQ,CAAA,IAAA,CAAK,KAAO,EAAA;AACvB,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,mBAAA,EAAqB,IAAM,EAAA,MAAA,EAAQ,CAAA;AACvE,MAAA;AAAA;AAGF,IAAA,MAAM,EAAE,KAAO,EAAA,OAAA,EAAS,IAAM,EAAA,QAAA,KAAa,OAAQ,CAAA,IAAA;AAEnD,IAAM,MAAA,CAAC,QAAQ,UAAY,EAAA,cAAA,EAAgB,aAAa,CACtD,GAAA,MAAM,eAAe,OAAS,EAAA;AAAA,MAC5B,cAAgB,EAAA,IAAA;AAAA,MAChB,eAAiB,EAAA,KAAA;AAAA,MACjB,kBAAoB,EAAA,KAAA;AAAA,MACpB,cAAgB,EAAA;AAAA,KACjB,CAAA;AAEH,IAAM,MAAA,KAAA,GAAQ,MAAM,QAAS,CAAA,YAAA;AAAA,MAC3B,QAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,MACA,EAAE,UAAY,EAAA,cAAA,EAAgB,aAAc;AAAA,KAC9C;AAEA,IAAA,MAAMA,0BAAoB,CAAA,OAAA,EAAS,KAAM,CAAA,KAAA,EAAO,OAAS,EAAA;AAAA,MACvD,WAAa,EAAA,KAAA;AAAA,MACb;AAAA,KACD,CAAA;AACD,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,GACpB,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,iBAAA,CAAA,EAAqB,OAAO,OAAA,EAAS,QAAa,KAAA;AAE3D,IAAA,MAAM,QAAW,GAAA,MAAM,aAAc,CAAA,WAAA,CAAY,SAAS,IAAI,CAAA;AAC9D,IAAM,MAAA,aAAA,GAAgB,GAAI,CAAA,OAAA,CAAQF,wBAAgB,CAAA;AAClD,IAAA,IAAI,CAAC,aAAA,CAAc,OAAQ,CAAA,KAAK,CAAG,EAAA;AACjC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,aAAc,CAAA,MAAA,EAAQ,IAAM,EAAA,OAAA,EAAS,CAAA;AACvD,MAAA;AAAA;AAGF,IAAM,MAAA,cAAA,GAA6B,EAAE,MAAA,EAAQ,QAAS,EAAA;AACtD,IAAM,MAAA,IAAA,GAAO,QAAQ,MAAO,CAAA,IAAA;AAC5B,IAAA,IAAI,SAAS,YAAc,EAAA;AACzB,MAAA,cAAA,CAAe,MAAS,GAAA,IAAA;AACxB,MAAA,cAAA,CAAe,SAAY,GAAA,IAAA;AAAA,KAC7B,MAAA,IAAW,SAAS,WAAa,EAAA;AAC/B,MAAA,cAAA,CAAe,eAAkB,GAAA,IAAA;AACjC,MAAA,cAAA,CAAe,MAAS,GAAA,IAAA;AAAA,KAC1B,MAAA,IAAW,SAAS,KAAO,EAAA;AACzB,MAAA,cAAA,CAAe,YAAe,GAAA,IAAA;AAC9B,MAAA,cAAA,CAAe,OAAU,GAAA,OAAA;AAAA,KAC3B,MAAA,IAAW,SAAS,KAAO,EAAA;AACzB,MAAA,cAAA,CAAe,MAAS,GAAA,QAAA;AAAA;AAE1B,IAAA,MAAM,OAAO,EAAE,GAAG,OAAQ,CAAA,KAAA,EAAO,GAAG,cAAe,EAAA;AAEnD,IAAM,MAAA,CAAC,QAAQ,UAAY,EAAA,cAAA,EAAgB,aAAa,CACtD,GAAA,MAAM,cAAe,CAAA,OAAA,EAAS,IAAI,CAAA;AAGpC,IAAM,MAAA,GAAA,GAAM,mBAAmB,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAI,CAAA,EAAA,IAAA,CAAK,SAAU,CAAA,IAAI,CAAC,CAAA,CAAA;AACvE,IAAA,MAAM,MAAM,GAAM,GAAA,GAAA;AAElB,IAAA,MAAM,QAAQ,MAAMG,uBAAA;AAAA,MAClB,OAAQ,CAAA,KAAA;AAAA,MACR,GAAA;AAAA,MACA,GAAA;AAAA,MACA,YAAY;AACV,QAAA,OAAO,MAAM,QAAA,CAAS,QAAS,CAAA,QAAA,EAAU,MAAM,MAAQ,EAAA;AAAA,UACrD,YAAc,EAAA,KAAA;AAAA,UACd,cAAgB,EAAA,KAAA;AAAA,UAChB,kBAAoB,EAAA,KAAA;AAAA,UACpB,eAAiB,EAAA,KAAA;AAAA,UACjB,WAAa,EAAA,KAAA;AAAA,UACb,YAAc,EAAA,KAAA;AAAA,UACd,cAAgB,EAAA,KAAA;AAAA,UAChB,eAAiB,EAAA,KAAA;AAAA,UACjB,cAAA;AAAA,UACA,UAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,OACH;AAAA,MACA,OAAQ,CAAA;AAAA,KACV;AAEA,IAAA,MAAMD,0BAAoB,CAAA,OAAA,EAAS,KAAM,CAAA,KAAA,EAAO,OAAS,EAAA;AAAA,MACvD,WAAA,EAAa,KAAK,WAAe,IAAA,KAAA;AAAA,MACjC;AAAA,KACD,CAAA;AACD,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,GACpB,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,UAAA,CAAA,EAAc,OAAO,OAAA,EAAS,QAAa,KAAA;AACpD,IAAM,MAAA,aAAA,GAAgB,GAAI,CAAA,OAAA,CAAQE,uBAAe,CAAA;AACjD,IAAA,IAAI,CAAC,aAAA,CAAc,OAAQ,CAAA,KAAK,CAAG,EAAA;AACjC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,aAAc,CAAA,MAAA,EAAQ,IAAM,EAAA,OAAA,EAAS,CAAA;AACvD,MAAA;AAAA;AAEF,IAAM,MAAA,SAAA,GAAY,QAAQ,KAAM,CAAA,SAAA;AAEhC,IAAA,MAAM,MAAM,MAAM,qBAAA;AAAA,MAChB,OAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA,GAAY,CAAC,SAAY,GAAA,IAAA;AAAA,MACzB;AAAA,KACF;AACA,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA,EAAE,IAAM,EAAA,QAAA,EAAa,GAAA,GAAA;AAE3B,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYR,gDAAwB,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,MACvD,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAM,MAAAM,0BAAA,CAAoB,SAAS,CAAC,IAAI,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAChE,IAAA,IAAI,CAAC,SAAW,EAAA;AACd,MAAAG,oBAAA,CAAgB,SAAS,IAAI,CAAA;AAAA;AAG/B,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,WAAA;AAAA,MACT,aAAe,EAAA,KAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA,EAAE,IAAM,EAAAC,uBAAA,CAAmB,IAAI,CAAE;AAAA,KACxC,CAAA;AAED,IAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,GACnB,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,mBAAA,CAAA,EAAuB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC9D,IAAA,MAAM,MAAM,MAAM,qBAAA,CAAsB,OAAS,EAAA,QAAA,EAAU,OAAO,IAAI,CAAA;AACtE,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAA,MAAM,EAAE,IAAM,EAAA,QAAA,EAAU,aAAe,EAAA,UAAA,EAAY,gBAAmB,GAAA,GAAA;AAEtE,IAAA,MAAM,OAAU,GAAA,MAAMC,iBAAW,CAAA,OAAA,EAAS,OAAO,CAAA;AACjD,IAAM,MAAA,mBAAA,GAAsB,GAAI,CAAA,OAAA,CAAQC,qBAAa,CAAA;AACrD,IAAA,IAAI,CAAC,mBAAA,CAAoB,OAAQ,CAAA,IAAI,CAAG,EAAA;AACtC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,MAAA;AAAA;AAGF,IAAI,IAAA,IAAA,CAAK,WAAW,UAAY,EAAA;AAC9B,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,QACxB,MAAQ,EAAA,uCAAA;AAAA,QACR,IAAM,EAAA;AAAA,OACP,CAAA;AACD,MAAA;AAAA;AAGF,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA;AAAA,QACE,EAAE,UAAA,EAAYZ,gDAAwB,EAAA,QAAA,EAAU,IAAK,EAAA;AAAA,QACrD,EAAE,YAAYa,qDAA4B;AAAA,OAC5C;AAAA,MACA,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAM,MAAA,WAAA,GAAc,MAAM,QAAS,CAAA,WAAA;AAAA,MACjC,IAAK,CAAA,EAAA;AAAA,MACL,QAAA;AAAA,MACA,QAAQ,IAAK,CAAA,OAAA;AAAA,MACb,OAAA;AAAA,MACA,EAAE,UAAY,EAAA,cAAA,EAAgB,aAAc;AAAA,KAC9C;AAEA,IAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,wBAAA,EAA0B,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC1D,MAAA;AAAA;AAGF,IAAM,MAAAP,0BAAA,CAAoB,SAAS,CAAC,WAAW,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAEvE,IAAAQ,cAAA,CAAU,YAAY;AACpB,MAAA,IAAI,CAAC,WAAA,IAAe,WAAY,CAAA,MAAA,KAAW,QAAU,EAAA;AACnD,QAAA;AAAA;AAEF,MAAM,MAAA,cAAA,GAAiB,MAAM,OAAA,CAAQ,GAAI,CAAA;AAAA,QACvC,QAAA,CAAS,eAAgB,CAAA,WAAA,CAAY,IAAI,CAAA;AAAA,QACzC,QAAA,CAAS,mBAAoB,CAAA,WAAA,CAAY,QAAQ,CAAA;AAAA,QACjD,QAAA,CAAS,kBAAkB,QAAQ,CAAA;AAAA,QACnC,QAAA,CAAS,wBAAyB,CAAA,WAAA,CAAY,EAAE;AAAA,OACjD,CAAA;AAED,MAAM,MAAA,IAAA,GAAO,MAAM,eAAgB,CAAA,gBAAA;AAAA,QACjC,QAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAQ,IAAK,CAAA,OAAA;AAAA,QACb,eAAe,IAAK;AAAA,OACtB;AACA,MAAA,MAAM,QAAW,GAAAC,4CAAA,CAAmB,OAAQ,CAAA,IAAA,CAAK,OAAO,CAAA;AACxD,MAAI,IAAA,QAAA,CAAS,SAAS,CAAG,EAAA;AACvB,QAAA,MAAM,eAAgB,CAAA,SAAA;AAAA,UACpB,QAAA;AAAA,UACA,WAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA;AAAA,UACA;AAAA,SACF;AAAA;AACF,KACD,CAAA;AAED,IAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,MACd,KAAO,EAAA,MAAA;AAAA,MACP,YAAc,EAAA;AAAA,QACZ,IAAM,EAAA,WAAA;AAAA,QACN,OAAA,EAAS,QAAQ,IAAK,CAAA,OAAA;AAAA,QACtB,MAAQ,EAAA;AAAA,OACV;AAAA,MACA,QAAA,EAAU,EAAE,MAAA,EAAQ,cAAe;AAAA,KACpC,CAAA;AAED,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,cAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA;AAAA,QACJ,IAAA,EAAML,wBAAmB,WAAW,CAAA;AAAA,QACpC,OAAA,EAAS,QAAQ,IAAK,CAAA;AAAA;AACxB,KACD,CAAA;AAED,IAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,WAAW,CAAA;AAAA,GACtC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,8BAAA,CAAA,EAAkC,OAAO,OAAA,EAAS,QAAa,KAAA;AAGzE,IAAA,MAAM,SAAS,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,IAAI,EAAE,CAAA;AACpD,IAAA,MAAM,YAAY,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,WAAW,EAAE,CAAA;AAC9D,IAAA,IAAI,OAAO,KAAM,CAAA,MAAM,KAAK,MAAO,CAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACnD,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,YAAA,EAAc,IAAM,EAAA,MAAA,EAAQ,CAAA;AAChE,MAAA;AAAA;AAGF,IAAA,MAAM,MAAM,MAAM,qBAAA,CAAsB,OAAS,EAAA,QAAA,EAAU,OAAO,IAAI,CAAA;AACtE,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAA,MAAM,EAAE,IAAM,EAAA,QAAA,EAAU,aAAe,EAAA,cAAA,EAAgB,YAAe,GAAA,GAAA;AAEtE,IAAI,IAAA,IAAA,CAAK,WAAW,UAAY,EAAA;AAC9B,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,QACxB,MAAQ,EAAA,wCAAA;AAAA,QACR,IAAM,EAAA;AAAA,OACP,CAAA;AACD,MAAA;AAAA;AAGF,IAAA,MAAM,UAAU,MAAM,QAAA,CAAS,WAAW,SAAW,EAAA,EAAE,QAAQ,CAAA;AAE/D,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,mBAAA,EAAqB,IAAM,EAAA,MAAA,EAAQ,CAAA;AACvE,MAAA;AAAA;AAGF,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYM,mDAA2B,EAAA,QAAA,EAAU,SAAS,CAAA;AAAA,MAC7D,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAM,MAAA,WAAA,GAAc,MAAM,QAAS,CAAA,iBAAA;AAAA,MACjC,MAAA;AAAA,MACA,SAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAQ,IAAK,CAAA,OAAA;AAAA,MACb;AAAA,QACE,UAAA;AAAA,QACA,cAAA;AAAA,QACA;AAAA;AACF,KACF;AAEA,IAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,+BAAA,EAAiC,IAAM,EAAA,MAAA,EAAQ,CAAA;AACjE,MAAA;AAAA;AAGF,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,gBAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA;AAAA,QACJ,IAAA,EAAMN,wBAAmB,WAAW,CAAA;AAAA,QACpC,IAAA,EAAMA,wBAAmB,OAAO,CAAA;AAAA,QAChC,EAAA,EAAI,QAAQ,IAAK,CAAA;AAAA;AACnB,KACD,CAAA;AAED,IAAM,MAAAJ,0BAAA,CAAoB,SAAS,CAAC,WAAW,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAGvE,IAAA,QAAA,CAAS,KAAK,WAAW,CAAA;AAAA,GAC1B,CAAA;AAGD,EAAA,MAAA,CAAO,MAAO,CAAA,CAAA,8BAAA,CAAA,EAAkC,OAAO,OAAA,EAAS,QAAa,KAAA;AAG3E,IAAA,MAAM,SAAS,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,IAAI,EAAE,CAAA;AACpD,IAAA,MAAM,YAAY,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,WAAW,EAAE,CAAA;AAC9D,IAAA,IAAI,OAAO,KAAM,CAAA,MAAM,KAAK,MAAO,CAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACnD,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,YAAA,EAAc,IAAM,EAAA,MAAA,EAAQ,CAAA;AAChE,MAAA;AAAA;AAGF,IAAA,MAAM,MAAM,MAAM,qBAAA,CAAsB,OAAS,EAAA,QAAA,EAAU,OAAO,IAAI,CAAA;AACtE,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAA,MAAM,EAAE,IAAM,EAAA,QAAA,EAAU,aAAe,EAAA,UAAA,EAAY,gBAAmB,GAAA,GAAA;AAEtE,IAAI,IAAA,IAAA,CAAK,WAAW,UAAY,EAAA;AAC9B,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,QACxB,MAAQ,EAAA,0CAAA;AAAA,QACR,IAAM,EAAA;AAAA,OACP,CAAA;AACD,MAAA;AAAA;AAGF,IAAA,MAAM,UAAU,MAAM,QAAA,CAAS,WAAW,SAAW,EAAA,EAAE,QAAQ,CAAA;AAE/D,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,mBAAA,EAAqB,IAAM,EAAA,MAAA,EAAQ,CAAA;AACvE,MAAA;AAAA;AAGF,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYW,qDAA6B,EAAA,QAAA,EAAU,SAAS,CAAA;AAAA,MAC/D,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,IAAI,WAAc,GAAA,IAAA;AAClB,IAAA,IAAI,QAAQ,MAAW,KAAA,SAAA,IAAa,OAAQ,CAAA,IAAA,EAAM,cAAc,IAAM,EAAA;AACpE,MAAA,IAAI,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CAAI,EAAA;AAC/C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,mBAAA,EAAqB,IAAM,EAAA,OAAA,EAAS,CAAA;AACtD,QAAA;AAAA;AAEF,MAAA,WAAA,GAAc,MAAM,QAAS,CAAA,iBAAA;AAAA,QAC3B,MAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA,UACE,UAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA;AACF,OACF;AAAA,KACK,MAAA;AACL,MAAA,WAAA,GAAc,MAAM,QAAS,CAAA,iBAAA;AAAA,QAC3B,MAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,UACE,UAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA;AACF,OACF;AAAA;AAGF,IAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,+BAAA,EAAiC,IAAM,EAAA,MAAA,EAAQ,CAAA;AACjE,MAAA;AAAA;AAGF,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,gBAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA;AAAA,QACJ,IAAA,EAAMP,wBAAmB,WAAW,CAAA;AAAA,QACpC,OAAA,EAASA,wBAAmB,OAAO;AAAA;AACrC,KACD,CAAA;AAED,IAAM,MAAAJ,0BAAA,CAAoB,SAAS,CAAC,WAAW,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAGvE,IAAA,QAAA,CAAS,KAAK,WAAW,CAAA;AAAA,GAC1B,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,MAAA,CAAA,EAAU,OAAO,OAAA,EAAS,QAAa,KAAA;AAEjD,IAAM,MAAA,mBAAA,GAAsB,GAAI,CAAA,OAAA,CAAQY,kBAAU,CAAA;AAClD,IAAA,IAAI,CAAC,mBAAA,CAAoB,OAAQ,CAAA,IAAI,CAAG,EAAA;AACtC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,MAAA;AAAA;AAEF,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAY,EAAAC,kDAAA,EAA0B,CAAA;AAAA,MACzC,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAM,MAAA,YAAA,GAAe,MAAM,QAAA,CAAS,OAAQ,EAAA;AAC5C,IAAM,MAAA,CAAC,MAAM,QAAU,EAAA,QAAA,EAAU,OAAO,CAAI,GAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,MAC5DC,iBAAA,CAAQ,OAAS,EAAA,OAAA,EAAS,YAAY,CAAA;AAAA,MACtCC,qBAAA,CAAY,SAAS,MAAM,CAAA;AAAA,MAC3B,aAAA,CAAc,YAAY,OAAO,CAAA;AAAA,MACjCV,iBAAA,CAAW,SAAS,OAAO;AAAA,KAC5B,CAAA;AAED,IAAA,IAAI,QAAQ,IAAK,CAAA,MAAA,IAAU,OAAQ,CAAA,IAAA,CAAK,WAAW,QAAU,EAAA;AAC3D,MAAA,IAAI,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CAAI,EAAA;AAC/C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,QAAA;AAAA;AACF;AAIF,IAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,UAAW,CAAA;AAAA,MACrC,QAAU,EAAA,QAAA;AAAA,MACV,KAAA,EAAO,QAAQ,IAAK,CAAA,KAAA;AAAA,MACpB,OAAA,EAAS,QAAQ,IAAK,CAAA,OAAA;AAAA,MACtB,MAAA,EAAQ,QAAQ,IAAK,CAAA,MAAA;AAAA,MACrB,OAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA,EAAQ,QAAQ,IAAK,CAAA,MAAA;AAAA,MACrB,SAAW,EAAA,OAAA,CAAQ,IAAK,CAAA,SAAA,IAAa,QAAa,KAAA,oBAAA;AAAA,MAClD,IAAA,EAAM,QAAQ,IAAK,CAAA,IAAA;AAAA,MACnB,WAAA,EAAa,QAAQ,IAAK,CAAA,WAAA;AAAA,MAC1B,GAAA,EAAK,QAAQ,IAAK,CAAA,GAAA;AAAA,MAClB,MAAA,EAAQ,OAAQ,CAAA,IAAA,CAAK,MAAU,IAAA,QAAA;AAAA,MAC/B,IAAM,EAAA;AAAA,QACJ,eAAiB,EAAA,KAAA;AAAA,QACjB,YAAc,EAAA,KAAA;AAAA,QACd,cAAgB,EAAA;AAAA;AAClB,KACD,CAAA;AAED,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,MAAA,EAAQ,CAAA;AACpE,MAAA;AAAA;AAGF,IAAAG,cAAA,CAAU,YAAY;AACpB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,KAAW,QAAU,EAAA;AACrC,QAAA;AAAA;AAEF,MAAM,MAAA,cAAA,GAAiB,MAAM,OAAA,CAAQ,GAAI,CAAA;AAAA,QACvC,QAAA,CAAS,gBAAgB,IAAI,CAAA;AAAA,QAC7B,QAAA,CAAS,oBAAoB,QAAQ,CAAA;AAAA,QACrC,QAAA,CAAS,kBAAkB,QAAQ,CAAA;AAAA,QACnC,QAAA,CAAS,wBAAyB,CAAA,IAAA,CAAK,EAAE;AAAA,OAC1C,CAAA;AACD,MAAM,MAAA,IAAA,GAAO,MAAM,eAAgB,CAAA,SAAA;AAAA,QACjC,QAAA;AAAA,QACA,IAAA;AAAA,QACA,eAAe,IAAK;AAAA,OACtB;AACA,MAAA,MAAM,QAAW,GAAAC,4CAAA,CAAmB,OAAQ,CAAA,IAAA,CAAK,OAAO,CAAA;AACxD,MAAI,IAAA,QAAA,CAAS,SAAS,CAAG,EAAA;AACvB,QAAA,MAAM,eAAgB,CAAA,SAAA,CAAU,QAAU,EAAA,IAAA,EAAM,UAAU,IAAI,CAAA;AAAA;AAChE,KACD,CAAA;AAED,IAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,MACd,KAAO,EAAA,MAAA;AAAA,MACP,YAAc,EAAA;AAAA,QACZ,IAAA;AAAA,QACA,MAAQ,EAAA;AAAA,OACV;AAAA,MACA,QAAA,EAAU,EAAE,MAAA,EAAQ,UAAW;AAAA,KAChC,CAAA;AAED,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,aAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA;AAAA,QACJ,IAAA,EAAML,wBAAmB,IAAI;AAAA;AAC/B,KACD,CAAA;AAED,IAAM,MAAAJ,0BAAA,CAAoB,SAAS,CAAC,IAAI,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAGhE,IAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA;AAAA,GAC/B,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,UAAA,CAAA,EAAc,OAAO,OAAA,EAAS,QAAa,KAAA;AAGrD,IAAM,MAAA,mBAAA,GAAsB,GAAI,CAAA,OAAA,CAAQY,kBAAU,CAAA;AAClD,IAAA,IAAI,CAAC,mBAAA,CAAoB,OAAQ,CAAA,IAAI,CAAG,EAAA;AACtC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,MAAA;AAAA;AAGF,IAAA,MAAM,MAAM,MAAM,qBAAA,CAAsB,OAAS,EAAA,QAAA,EAAU,OAAO,IAAI,CAAA;AACtE,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA;AAAA,MACJ,IAAM,EAAA,YAAA;AAAA,MACN,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACE,GAAA,GAAA;AAEJ,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYI,gDAAwB,EAAA,QAAA,EAAU,cAAc,CAAA;AAAA,MAC/D,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,IAAI,QAAQ,IAAK,CAAA,MAAA,KAAW,QAAY,IAAA,YAAA,CAAa,WAAW,QAAU,EAAA;AACxE,MAAA,IAAI,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CAAI,EAAA;AAC/C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,QAAA;AAAA;AACF;AAGF,IACE,IAAA,OAAA,CAAQ,IAAK,CAAA,MAAA,IACb,OAAQ,CAAA,IAAA,CAAK,MAAW,KAAA,QAAA,IACxB,OAAQ,CAAA,IAAA,CAAK,MAAW,KAAA,YAAA,CAAa,MACrC,EAAA;AACA,MAAA,IAAI,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CAAI,EAAA;AAC/C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,QAAA;AAAA;AACF;AAGF,IAAM,MAAA,YAAA,GAAe,MAAM,QAAA,CAAS,OAAQ,EAAA;AAC5C,IAAA,MAAM,CAAC,IAAM,EAAA,QAAQ,CAAI,GAAA,MAAM,QAAQ,GAAI,CAAA;AAAA,MACzCF,iBAAA,CAAQ,OAAS,EAAA,OAAA,EAAS,YAAY,CAAA;AAAA,MACtCC,qBAAA,CAAY,SAAS,MAAM;AAAA,KAC5B,CAAA;AAGD,IAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,UAAW,CAAA;AAAA,MACrC,EAAI,EAAA,MAAA;AAAA,MACJ,QAAU,EAAA,QAAA;AAAA,MACV,MAAA,EAAQ,QAAQ,IAAK,CAAA,MAAA;AAAA,MACrB,KAAA,EAAO,QAAQ,IAAK,CAAA,KAAA;AAAA,MACpB,OAAA,EAAS,QAAQ,IAAK,CAAA,OAAA;AAAA,MACtB,IAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA,EAAQ,QAAQ,IAAK,CAAA,MAAA;AAAA,MACrB,WAAA,EAAa,QAAQ,IAAK,CAAA,WAAA;AAAA,MAC1B,GAAA,EAAK,QAAQ,IAAK,CAAA,GAAA;AAAA,MAClB,MAAA,EAAQ,OAAQ,CAAA,IAAA,CAAK,MAAU,IAAA,QAAA;AAAA,MAC/B,YAAA,EAAc,aAAa,MAAW,KAAA,OAAA;AAAA,MACtC,IAAM,EAAA,EAAE,UAAY,EAAA,cAAA,EAAgB,aAAc;AAAA,KACnD,CAAA;AAED,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAAP,cAAA,CAAU,YAAY;AACpB,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,KAAW,QAAU,EAAA;AACrC,QAAA;AAAA;AAEF,MAAM,MAAA,OAAA,GAAU,KAAK,MAAO,CAAA,CAAA,CAAA,KAAK,CAAC,YAAa,CAAA,IAAA,EAAM,QAAS,CAAA,CAAC,CAAC,CAAA;AAChE,MAAA,MAAM,cAAc,QAAS,CAAA,MAAA;AAAA,QAC3B,CAAK,CAAA,KAAA,CAAC,YAAa,CAAA,QAAA,EAAU,SAAS,CAAC;AAAA,OACzC;AAEA,MAAM,MAAA,cAAA,GAAiB,MAAM,OAAA,CAAQ,GAAI,CAAA;AAAA,QACvC,QAAA,CAAS,gBAAgB,OAAO,CAAA;AAAA,QAChC,QAAA,CAAS,oBAAoB,WAAW;AAAA,OACzC,CAAA;AAED,MAAM,MAAA,IAAA,GAAO,MAAM,eAAgB,CAAA,UAAA;AAAA,QACjC,QAAA;AAAA,QACA,IAAA;AAAA,QACA,eAAe,IAAK;AAAA,OACtB;AACA,MAAM,MAAA,gBAAA,GAAmBC,4CAAmB,CAAA,YAAA,CAAa,OAAO,CAAA;AAChE,MAAA,MAAM,QAAW,GAAAA,4CAAA,CAAmB,OAAQ,CAAA,IAAA,CAAK,OAAO,CAAA;AACxD,MAAM,MAAA,WAAA,GAAc,SAAS,MAAO,CAAA,CAAA,CAAA,KAAK,CAAC,gBAAiB,CAAA,QAAA,CAAS,CAAC,CAAC,CAAA;AAEtE,MAAI,IAAA,WAAA,CAAY,SAAS,CAAG,EAAA;AAC1B,QAAA,MAAM,eAAgB,CAAA,SAAA,CAAU,QAAU,EAAA,IAAA,EAAM,aAAa,IAAI,CAAA;AAAA;AACnE,KACD,CAAA;AAED,IAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,MACd,KAAO,EAAA,MAAA;AAAA,MACP,YAAc,EAAA;AAAA,QACZ,IAAA;AAAA,QACA,MAAQ,EAAA;AAAA,OACV;AAAA,MACA,QAAA,EAAU,EAAE,MAAA,EAAQ,aAAc;AAAA,KACnC,CAAA;AAED,IAAM,MAAAT,0BAAA,CAAoB,SAAS,CAAC,IAAI,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAEhE,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,aAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA;AAAA,QACJ,IAAA,EAAMI,wBAAmB,YAAY,CAAA;AAAA,QACrC,EAAA,EAAIA,wBAAmB,IAAI;AAAA;AAC7B,KACD,CAAA;AAGD,IAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,GACnB,CAAA;AAGD,EAAA,MAAA,CAAO,MAAO,CAAA,YAAA,EAAc,OAAO,OAAA,EAAS,QAAa,KAAA;AACvD,IAAA,MAAM,MAAM,MAAM,qBAAA,CAAsB,OAAS,EAAA,QAAA,EAAU,OAAO,IAAI,CAAA;AACtE,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA,mBAAA,GAAsB,GAAI,CAAA,OAAA,CAAQa,4BAAoB,CAAA;AAC5D,IAAA,IAAI,CAAC,mBAAA,CAAoB,OAAQ,CAAA,IAAI,CAAG,EAAA;AACtC,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,cAAA,EAAgB,IAAM,EAAA,MAAA,EAAQ,CAAA;AAClE,MAAA;AAAA;AAGF,IAAM,MAAA,EAAE,IAAM,EAAA,QAAA,EAAa,GAAA,GAAA;AAE3B,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYC,kDAA0B,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,MACzD,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,IAAI,OAAU,GAAA,KAAA;AACd,IAAA,IAAI,KAAK,MAAW,KAAA,SAAA,IAAa,OAAQ,CAAA,IAAA,EAAM,cAAc,IAAM,EAAA;AACjE,MAAA,IAAI,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CAAI,EAAA;AAC/C,QAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,QAAA;AAAA;AAEF,MAAA,OAAA,GAAU,MAAM,QAAA,CAAS,UAAW,CAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,KAC5C,MAAA;AACL,MAAA,OAAA,GAAU,MAAM,QAAA,CAAS,UAAW,CAAA,IAAA,CAAK,EAAE,CAAA;AAC3C,MAAA,IAAI,OAAS,EAAA;AACX,QAAA,eAAA,CAAgB,YAAa,CAAA,QAAA,EAAU,IAAM,EAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA;AAClE;AAGF,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,QACd,KAAO,EAAA,MAAA;AAAA,QACP,YAAc,EAAA;AAAA,UACZ,IAAA;AAAA,UACA,QAAQ,IAAK,CAAA,MAAA;AAAA,UACb,MAAA,EAAQ,QAAQ,IAAK,CAAA;AAAA,SACvB;AAAA,QACA,QAAA,EAAU,EAAE,MAAA,EAAQ,aAAc;AAAA,OACnC,CAAA;AAED,MAAA,OAAA,EAAS,WAAY,CAAA;AAAA,QACnB,OAAS,EAAA,aAAA;AAAA,QACT,aAAe,EAAA,QAAA;AAAA,QACf,OAAA;AAAA,QACA,IAAA,EAAM,EAAE,IAAM,EAAAd,uBAAA,CAAmB,IAAI,CAAG,EAAA,MAAA,EAAQ,OAAQ,CAAA,IAAA,CAAK,MAAO;AAAA,OACrE,CAAA;AAAA;AAGH,IAAS,QAAA,CAAA,UAAA,CAAW,OAAU,GAAA,GAAA,GAAM,GAAG,CAAA;AAAA,GACxC,CAAA;AAED,EAAA,MAAM,QAAW,GAAA,OACf,OACA,EAAA,QAAA,EACA,KACG,KAAA;AACH,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA;AAAA,MACJ,IAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACE,GAAA,GAAA;AAEJ,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYV,gDAAwB,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,MACvD,EAAE,aAAa,IAAK;AAAA,KACtB;AACA,IAAA,IAAI,KAAK,GAAK,EAAA;AACZ,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,+BAAA,EAAiC,IAAM,EAAA,MAAA,EAAQ,CAAA;AACjE,MAAA;AAAA;AAGF,IAAA,MAAM,QAAQ,MAAM,QAAA,CAAS,QAAS,CAAA,QAAA,EAAU,QAAQ,KAAK,CAAA;AAE7D,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,MAAA,EAAQ,CAAA;AACpE,MAAA;AAAA;AAGF,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,OAAQ,CAAA,QAAA,EAAU,QAAQ,KAAO,EAAA;AAAA,MAC3D,aAAA;AAAA,MACA,UAAA;AAAA,MACA,cAAA;AAAA,MACA,eAAiB,EAAA,KAAA;AAAA,MACjB,cAAgB,EAAA,KAAA;AAAA,MAChB,kBAAoB,EAAA,KAAA;AAAA,MACpB,WAAa,EAAA,KAAA;AAAA,MACb,eAAiB,EAAA;AAAA,KAClB,CAAA;AACD,IAAA,IAAI,SAAS,IAAM,EAAA;AACjB,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,MACd,KAAO,EAAA,MAAA;AAAA,MACP,YAAc,EAAA;AAAA,QACZ,IAAA;AAAA,QACA,MAAQ,EAAA,QAAA;AAAA,QACR;AAAA,OACF;AAAA,MACA,QAAA,EAAU,EAAE,MAAA,EAAQ,WAAY;AAAA,KACjC,CAAA;AAED,IAAM,MAAAM,0BAAA,CAAoB,SAAS,CAAC,IAAI,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAChE,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA;AAEf,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,MAAA;AAAA,MACT,aAAe,EAAA,KAAA;AAAA,MACf,OAAA;AAAA,MACA,MAAM,EAAE,IAAA,EAAMI,uBAAmB,CAAA,IAAI,GAAG,KAAM;AAAA,KAC/C,CAAA;AAED,IAAAD,oBAAA,CAAgB,SAAS,IAAI,CAAA;AAG7B,IAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,GACpB;AAGA,EAAA,MAAA,CAAO,IAAK,CAAA,oBAAA,EAAsB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC7D,IAAA,MAAM,MAAM,MAAM,qBAAA,CAAsB,OAAS,EAAA,QAAA,EAAU,OAAO,IAAI,CAAA;AACtE,IAAA,IAAI,CAAC,GAAK,EAAA;AAEV,IAAA,IAAI,CAAE,MAAM,aAAc,CAAA,WAAA,CAAY,OAAO,CAAI,EAAA;AAC/C,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAA;AAAA;AAEF,IAAM,MAAA;AAAA,MACJ,IAAM,EAAA,YAAA;AAAA,MACN,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACE,GAAA,GAAA;AAGJ,IAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,UAAW,CAAA;AAAA,MACrC,EAAI,EAAA,MAAA;AAAA,MACJ,MAAQ,EAAA,QAAA;AAAA,MACR,QAAU,EAAA,QAAA;AAAA,MACV,YAAc,EAAA,KAAA;AAAA,MACd,IAAM,EAAA,EAAE,UAAY,EAAA,cAAA,EAAgB,aAAc;AAAA,KACnD,CAAA;AAED,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,MACd,KAAO,EAAA,MAAA;AAAA,MACP,YAAc,EAAA;AAAA,QACZ,IAAA;AAAA,QACA,MAAQ,EAAA;AAAA,OACV;AAAA,MACA,QAAA,EAAU,EAAE,MAAA,EAAQ,cAAe;AAAA,KACpC,CAAA;AAED,IAAM,MAAAH,0BAAA,CAAoB,SAAS,CAAC,IAAI,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAEhE,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,cAAA;AAAA,MACT,aAAe,EAAA,QAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA;AAAA,QACJ,IAAA,EAAMI,wBAAmB,YAAY,CAAA;AAAA,QACrC,EAAA,EAAIA,wBAAmB,IAAI;AAAA;AAC7B,KACD,CAAA;AAGD,IAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,GACnB,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,kBAAA,EAAoB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC1D,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACR,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAA;AAAA;AAEF,IAAM,MAAA,EAAE,MAAQ,EAAA,QAAA,EAAa,GAAA,GAAA;AAC7B,IAAM,MAAA,QAAA,CAAS,SAAU,CAAA,QAAA,EAAU,MAAM,CAAA;AAEzC,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,OAAQ,CAAA,QAAA,EAAU,QAAQ,KAAO,EAAA;AAAA,MAC3D,eAAiB,EAAA,KAAA;AAAA,MACjB,cAAgB,EAAA,KAAA;AAAA,MAChB,kBAAoB,EAAA,KAAA;AAAA,MACpB,WAAa,EAAA,KAAA;AAAA,MACb,eAAiB,EAAA;AAAA,KAClB,CAAA;AAED,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,gBAAA,EAAkB,IAAM,EAAA,OAAA,EAAS,CAAA;AACrE,MAAA;AAAA;AAGF,IAAAD,oBAAA,CAAgB,SAAS,IAAI,CAAA;AAC7B,IAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,CAAA;AAAA,GAC7B,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,iBAAA,CAAA,EAAqB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC3D,IAAA,OAAO,MAAM,QAAA,CAAS,OAAS,EAAA,QAAA,EAAU,CAAC,CAAA;AAAA,GAC3C,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,mBAAA,CAAA,EAAuB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC7D,IAAA,OAAO,MAAM,QAAA,CAAS,OAAS,EAAA,QAAA,EAAU,CAAE,CAAA,CAAA;AAAA,GAC5C,CAAA;AAED,EAAA,MAAA,CAAO,MAAO,CAAA,iBAAA,EAAmB,OAAO,OAAA,EAAS,QAAa,KAAA;AAE5D,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA;AAAA,MACJ,IAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACE,GAAA,GAAA;AAEJ,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYT,gDAAwB,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,MACvD,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,QAAS,CAAA,cAAA,CAAe,UAAU,MAAM,CAAA;AAC9D,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,OAAQ,CAAA,QAAA,EAAU,QAAQ,KAAO,EAAA;AAAA,MAC3D,aAAA;AAAA,MACA,UAAA;AAAA,MACA,cAAA;AAAA,MACA,eAAiB,EAAA,KAAA;AAAA,MACjB,cAAgB,EAAA,KAAA;AAAA,MAChB,kBAAoB,EAAA,KAAA;AAAA,MACpB,WAAa,EAAA,KAAA;AAAA,MACb,eAAiB,EAAA;AAAA,KAClB,CAAA;AAED,IAAA,IAAI,SAAS,IAAM,EAAA;AACjB,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAA,MAAA,EAAQ,OAAQ,CAAA;AAAA,MACd,KAAO,EAAA,MAAA;AAAA,MACP,YAAc,EAAA;AAAA,QACZ,IAAA;AAAA,QACA,MAAQ,EAAA;AAAA,OACV;AAAA,MACA,QAAA,EAAU,EAAE,MAAA,EAAQ,aAAc;AAAA,KACnC,CAAA;AAED,IAAM,MAAAM,0BAAA,CAAoB,SAAS,CAAC,IAAI,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAChE,IAAA,IAAA,CAAK,OAAU,GAAA,KAAA,CAAA;AAEf,IAAAG,oBAAA,CAAgB,SAAS,IAAI,CAAA;AAE7B,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,aAAA;AAAA,MACT,aAAe,EAAA,KAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA,EAAE,IAAM,EAAAC,uBAAA,CAAmB,IAAI,CAAE;AAAA,KACxC,CAAA;AACD,IAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,GACnB,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,mBAAA,EAAqB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC5D,IAAM,MAAA,mBAAA,GAAsB,GAAI,CAAA,OAAA,CAAQe,4BAAoB,CAAA;AAC5D,IAAA,IAAI,CAAC,mBAAA,CAAoB,OAAQ,CAAA,IAAI,CAAG,EAAA;AACtC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CACV,IAAK,CAAA,EAAE,QAAQ,mBAAoB,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AAC5D,MAAA;AAAA;AAGF,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA,EAAE,IAAM,EAAA,MAAA,EAAW,GAAA,GAAA;AAEzB,IAAA,MAAM,OAAO,MAAM,OAAA,CAAQ,aAAc,CAAA,WAAA,CAAY,SAAS,IAAI,CAAA;AAElE,IAAA,MAAM,QAAQ,aAAc,CAAA,SAAA;AAAA,MAC1B,OAAA;AAAA,MACA;AAAA,QACE,EAAE,UAAA,EAAYzB,gDAAwB,EAAA,QAAA,EAAU,IAAK,EAAA;AAAA,QACrD,EAAE,YAAY0B,wDAA+B;AAAA,OAC/C;AAAA,MACA,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAM,MAAA,WAAA,GAAc,MAAM,OAAA,CAAQ,QAAS,CAAA,UAAA;AAAA,MACzC,IAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAQ,IAAK,CAAA,MAAA;AAAA,MACb,QAAQ,IAAK,CAAA;AAAA,KACf;AACA,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAEF,IAAA,QAAA,CAAS,KAAK,WAAW,CAAA;AAAA,GAC1B,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,oBAAA,EAAsB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC5D,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA,EAAE,IAAM,EAAA,MAAA,EAAW,GAAA,GAAA;AAEzB,IAAA,MAAM,QAAQ,aAAc,CAAA,SAAA;AAAA,MAC1B,OAAA;AAAA,MACA;AAAA,QACE,EAAE,UAAA,EAAY1B,gDAAwB,EAAA,QAAA,EAAU,IAAK,EAAA;AAAA,QACrD,EAAE,YAAY2B,sDAA6B;AAAA,OAC7C;AAAA,MACA,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,OAAQ,CAAA,QAAA,CAAS,eAAe,MAAM,CAAA;AAC5D,IAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,GACtB,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,mBAAA,CAAA,EAAuB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC7D,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA;AAAA,MACJ,IAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACE,GAAA,GAAA;AAEJ,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAY3B,gDAAwB,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,MACvD,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,MAAM,SAAY,GAAA,MAAM,QAAS,CAAA,YAAA,CAAa,UAAU,MAAM,CAAA;AAE9D,IAAA,IAAI,CAAC,SAAW,EAAA;AACd,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAM,MAAA,WAAA,GAAc,MAAM,QAAS,CAAA,OAAA;AAAA,MACjC,QAAA;AAAA,MACA,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,IAAI,EAAE,CAAA;AAAA,MACrC,KAAA;AAAA,MACA;AAAA,QACE,aAAA;AAAA,QACA,UAAA;AAAA,QACA,cAAA;AAAA,QACA,eAAiB,EAAA,KAAA;AAAA,QACjB,cAAgB,EAAA,KAAA;AAAA,QAChB,eAAiB,EAAA,KAAA;AAAA,QACjB,YAAc,EAAA,KAAA;AAAA,QACd,WAAa,EAAA,KAAA;AAAA,QACb,kBAAoB,EAAA;AAAA;AACtB,KACF;AAEA,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,eAAA;AAAA,MACT,aAAe,EAAA,KAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA,EAAE,IAAM,EAAAU,uBAAA,CAAmB,WAAW,CAAE;AAAA,KAC/C,CAAA;AAED,IAAM,MAAAJ,0BAAA,CAAoB,SAAS,CAAC,WAAW,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAGvE,IAAA,QAAA,CAAS,KAAK,WAAW,CAAA;AAAA,GAC1B,CAAA;AAGD,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,qBAAA,CAAA,EAAyB,OAAO,OAAA,EAAS,QAAa,KAAA;AAC/D,IAAA,MAAM,GAAM,GAAA,MAAM,qBAAsB,CAAA,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,CAAC,GAAK,EAAA;AACV,IAAM,MAAA;AAAA,MACJ,IAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACE,GAAA,GAAA;AAEJ,IAAA,MAAM,aAAc,CAAA,SAAA;AAAA,MAClB,OAAA;AAAA,MACA,CAAC,EAAE,UAAA,EAAYN,gDAAwB,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,MACvD,EAAE,aAAa,IAAK;AAAA,KACtB;AAEA,IAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,cAAA,CAAe,UAAU,MAAM,CAAA;AAElE,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAM,MAAA,WAAA,GAAc,MAAM,QAAS,CAAA,OAAA;AAAA,MACjC,QAAA;AAAA,MACA,MAAO,CAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,IAAI,EAAE,CAAA;AAAA,MACrC,KAAA;AAAA,MACA;AAAA,QACE,aAAA;AAAA,QACA,UAAA;AAAA,QACA,cAAA;AAAA,QACA,eAAiB,EAAA,KAAA;AAAA,QACjB,cAAgB,EAAA,KAAA;AAAA,QAChB,eAAiB,EAAA,KAAA;AAAA,QACjB,YAAc,EAAA,KAAA;AAAA,QACd,WAAa,EAAA,KAAA;AAAA,QACb,kBAAoB,EAAA;AAAA;AACtB,KACF;AAEA,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AACvB,MAAA;AAAA;AAGF,IAAA,OAAA,EAAS,WAAY,CAAA;AAAA,MACnB,OAAS,EAAA,iBAAA;AAAA,MACT,aAAe,EAAA,KAAA;AAAA,MACf,OAAA;AAAA,MACA,IAAM,EAAA,EAAE,IAAM,EAAAU,uBAAA,CAAmB,WAAW,CAAE;AAAA,KAC/C,CAAA;AAED,IAAM,MAAAJ,0BAAA,CAAoB,SAAS,CAAC,WAAW,GAAG,OAAS,EAAA,EAAE,UAAU,CAAA;AAGvE,IAAA,QAAA,CAAS,KAAK,WAAW,CAAA;AAAA,GAC1B,CAAA;AAGD,EAAA,MAAA,CAAO,IAAK,CAAA,CAAA,IAAA,CAAA,EAAQ,OAAO,OAAA,EAAS,QAAa,KAAA;AAC/C,IAAM,MAAA,aAAA,GAAgB,GAAI,CAAA,OAAA,CAAQsB,yBAAiB,CAAA;AACnD,IAAA,IAAI,CAAC,aAAA,CAAc,OAAQ,CAAA,IAAI,CAAG,EAAA;AAChC,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA,EAAE,QAAQ,aAAc,CAAA,MAAA,EAAQ,IAAM,EAAA,MAAA,EAAQ,CAAA;AACxE,MAAA;AAAA;AAGF,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,OAAA,CAAQ,KAAK,GAAG,CAAA;AACpC,IAAA,IAAI,GAAI,CAAA,QAAA,KAAa,OAAW,IAAA,GAAA,CAAI,aAAa,QAAU,EAAA;AACzD,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,sBAAA,EAAwB,IAAM,EAAA,KAAA,EAAO,CAAA;AACvD,MAAA;AAAA;AAEF,IAAI,IAAA,GAAA,CAAI,aAAa,WAAa,EAAA;AAChC,MACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,uBAAA,EAAyB,IAAM,EAAA,KAAA,EAAO,CAAA;AACxD,MAAA;AAAA;AAGF,IAAA,MAAM,QAAW,GAAA,CAAA,aAAA,EAAgB,GAAI,CAAA,QAAA,EAAU,CAAA,CAAA;AAC/C,IAAA,MAAM,MAAS,GAAA,MAAM,KAAO,EAAA,GAAA,CAAI,QAAQ,CAAA;AACxC,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AACpB,MAAA;AAAA;AAGF,IAAA,MAAM,QAAW,GAAA,MAAMC,oBAAgB,CAAA,GAAA,EAAK,QAAQ,MAAM,CAAA;AAC1D,IAAM,MAAA,KAAA,EAAO,GAAI,CAAA,QAAA,EAAU,QAAU,EAAA,EAAE,KAAK,EAAE,KAAA,EAAO,CAAE,EAAA,EAAG,CAAA;AAC1D,IAAA,QAAA,CAAS,KAAK,QAAQ,CAAA;AAAA,GACvB,CAAA;AACH;;;;"}
|
|
1
|
+
{"version":3,"file":"posts.cjs.js","sources":["../../../src/service/routes/posts.ts"],"sourcesContent":["import { getCreated, mapAdditionalFields } from '../util';\nimport { durationToMilliseconds, HumanDuration } from '@backstage/types';\nimport Ajv from 'ajv';\nimport { Request, Router } from 'express';\nimport {\n findEntityMentions,\n PostsQuery,\n qetaCreateCommentPermission,\n qetaCreatePostPermission,\n qetaCreatePostReviewPermission,\n qetaDeleteCommentPermission,\n qetaDeletePostPermission,\n qetaEditCommentPermission,\n qetaEditPostPermission,\n qetaReadAnswerPermission,\n qetaReadCommentPermission,\n qetaReadPostPermission,\n qetaReadPostReviewPermission,\n qetaReadTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport addFormats from 'ajv-formats';\nimport {\n CommentSchema,\n DeleteMetadataSchema,\n PostQuerySchema,\n PostReviewBodySchema,\n PostSchema,\n PostsQuerySchema,\n RouteOptions,\n URLMetadataSchema,\n} from '../types';\nimport { Response } from 'express-serve-static-core';\nimport {\n entityToJsonObject,\n extractMetadata,\n signalPostStats,\n validateDateRange,\n wrapAsync,\n} from './util';\nimport { getCachedData, getEntities, getTags } from './routeUtil';\nimport { PostOptions } from '../../database/QetaStore';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const postsRoutes = (router: Router, options: RouteOptions) => {\n const {\n database,\n events,\n config,\n cache,\n signals,\n notificationMgr,\n auditor,\n permissionMgr,\n } = options;\n\n const postsOlderThan = config.getOptional<HumanDuration>(\n 'qeta.contentHealth.postsOlderThan',\n ) ?? { months: 6 };\n const reviewThresholdMs = durationToMilliseconds(postsOlderThan);\n\n const getPostFilters = async (request: Request, opts: PostOptions) => {\n return await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n opts.includeTags\n ? permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n })\n : undefined,\n opts.includeComments\n ? permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCommentPermission,\n { allowServicePrincipal: true },\n )\n : undefined,\n opts.includeAnswers\n ? permissionMgr.getAuthorizeConditions(\n request,\n qetaReadAnswerPermission,\n { allowServicePrincipal: true },\n )\n : undefined,\n ]);\n };\n\n const getPostAndCheckStatus = async (\n request: Request,\n response: Response,\n recordView?: boolean,\n allowServiceToken?: boolean,\n ) => {\n const username = await permissionMgr.getUsername(\n request,\n allowServiceToken,\n );\n const postId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(postId)) {\n response.status(400).send({ errors: 'Invalid post id', type: 'body' });\n return null;\n }\n\n const [tagsFilter, commentsFilter, answersFilter] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: allowServiceToken,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadCommentPermission, {\n allowServicePrincipal: allowServiceToken,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadAnswerPermission, {\n allowServicePrincipal: allowServiceToken,\n }),\n ]);\n\n const post = await database.getPost(username, postId, recordView, {\n tagsFilter,\n commentsFilter,\n answersFilter,\n includeHealth: true,\n reviewThresholdMs,\n });\n\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return null;\n }\n\n if (\n post.status === 'deleted' &&\n !(await permissionMgr.isModerator(request))\n ) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return null;\n }\n\n if (post.status === 'draft' && post.author !== username) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return null;\n }\n\n if (recordView === true) {\n signalPostStats(options.signals, { ...post, views: post.views + 1 });\n }\n\n return {\n post,\n username,\n postId,\n tagsFilter,\n commentsFilter,\n answersFilter,\n };\n };\n\n // GET /posts\n router.get(`/posts`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(PostsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const validDate = validateDateRange(\n request.query.fromDate as string,\n request.query.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const opts = request.query as PostsQuery;\n\n if (opts.reviewNeeded) {\n opts.obsolete = false;\n opts.includeHealth = true;\n }\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, opts);\n\n if (\n opts.status === 'deleted' &&\n !(await permissionMgr.isModerator(request))\n ) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n\n // Act\n const posts = await database.getPosts(username, opts, filter, {\n tagsFilter,\n commentsFilter,\n answersFilter,\n includeAnswers: false,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n includeHealth: opts.includeHealth,\n reviewThresholdMs,\n reviewNeeded: opts.reviewNeeded,\n });\n\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n response.json(posts);\n });\n\n router.post(`/posts/query`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(PostsQuerySchema);\n if (!validateQuery(request.body)) {\n response.status(400).send({ errors: validateQuery.errors, type: 'body' });\n return;\n }\n\n const validDate = validateDateRange(\n request.body.fromDate as string,\n request.body.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const opts = request.body;\n\n if (\n opts.status === 'deleted' &&\n !(await permissionMgr.isModerator(request))\n ) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, opts);\n\n if (opts.reviewNeeded) {\n opts.obsolete = false;\n opts.includeHealth = true;\n }\n\n // Act\n const posts = await database.getPosts(username, opts, filter, {\n tagsFilter,\n commentsFilter,\n answersFilter,\n includeAnswers: false,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n includeHealth: opts.includeHealth,\n reviewThresholdMs,\n reviewNeeded: opts.reviewNeeded,\n });\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n response.json(posts);\n });\n\n // POST /posts/suggest\n router.post(`/posts/suggest`, async (request, response) => {\n const username = await permissionMgr.getUsername(request, true);\n if (!request.body.title) {\n response.status(400).send({ errors: 'Title is required', type: 'body' });\n return;\n }\n\n const { title, content, tags, entities } = request.body;\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, {\n includeAnswers: true,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n });\n\n const posts = await database.suggestPosts(\n username,\n title,\n content,\n tags,\n entities,\n filter,\n { tagsFilter, commentsFilter, answersFilter },\n );\n\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: false,\n username,\n });\n response.json(posts);\n });\n\n // GET /posts/list/:type\n router.get(`/posts/list/:type`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(PostsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const optionOverride: PostsQuery = { status: 'active' };\n const type = request.params.type;\n if (type === 'unanswered') {\n optionOverride.random = true;\n optionOverride.noAnswers = true;\n } else if (type === 'incorrect') {\n optionOverride.noCorrectAnswer = true;\n optionOverride.random = true;\n } else if (type === 'hot') {\n optionOverride.includeTrend = true;\n optionOverride.orderBy = 'trend';\n } else if (type === 'own') {\n optionOverride.author = username;\n }\n const opts = { ...request.query, ...optionOverride };\n\n const [filter, tagsFilter, commentsFilter, answersFilter] =\n await getPostFilters(request, opts);\n\n // Act\n const key = `qeta:posts:list:${type}:${username}:${JSON.stringify(opts)}`;\n const ttl = 300 * 1000;\n\n const posts = await getCachedData(\n options.cache,\n key,\n ttl,\n async () => {\n return await database.getPosts(username, opts, filter, {\n includeTotal: false,\n includeAnswers: false,\n includeAttachments: false,\n includeEntities: false,\n includeTags: false,\n includeVotes: false,\n includeExperts: false,\n includeComments: false,\n commentsFilter,\n tagsFilter,\n answersFilter,\n });\n },\n options.logger,\n );\n\n await mapAdditionalFields(request, posts.posts, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n response.json(posts);\n });\n\n // GET /posts/:id\n router.get(`/posts/:id`, async (request, response) => {\n const validateQuery = ajv.compile(PostQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n const anonymous = request.query.anonymous as undefined | boolean;\n\n const ret = await getPostAndCheckStatus(\n request,\n response,\n anonymous ? !anonymous : true,\n true,\n );\n if (!ret) return;\n const { post, username } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n await mapAdditionalFields(request, [post], options, { username });\n if (!anonymous) {\n signalPostStats(signals, post);\n }\n\n auditor?.createEvent({\n eventId: 'read-post',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(post) },\n });\n\n response.json(post);\n });\n\n // POST /posts/:id/comments\n router.post(`/posts/:id/comments`, async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const { post, username, answersFilter, tagsFilter, commentsFilter } = ret;\n\n const created = await getCreated(request, options);\n const validateRequestBody = ajv.compile(CommentSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .send({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n if (post.status === 'obsolete') {\n response.status(400).send({\n errors: 'Cannot add comments to obsolete posts',\n type: 'body',\n });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaReadPostPermission, resource: post },\n { permission: qetaCreateCommentPermission },\n ],\n { throwOnDeny: true },\n );\n\n const updatedPost = await database.commentPost(\n post.id,\n username,\n request.body.content,\n created,\n { tagsFilter, commentsFilter, answersFilter },\n );\n\n if (updatedPost === null) {\n response\n .status(400)\n .send({ errors: 'Failed to comment post', type: 'body' });\n return;\n }\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n wrapAsync(async () => {\n if (!updatedPost || updatedPost.status !== 'active') {\n return;\n }\n const followingUsers = await Promise.all([\n database.getUsersForTags(updatedPost.tags),\n database.getUsersForEntities(updatedPost.entities),\n database.getFollowingUsers(username),\n database.getUsersWhoFavoritedPost(updatedPost.id),\n ]);\n\n const sent = await notificationMgr.onNewPostComment(\n username,\n updatedPost,\n request.body.content,\n followingUsers.flat(),\n );\n const mentions = findEntityMentions(request.body.content);\n if (mentions.length > 0) {\n await notificationMgr.onMention(\n username,\n updatedPost,\n mentions,\n sent,\n true,\n );\n }\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post: updatedPost,\n comment: request.body.content,\n author: username,\n },\n metadata: { action: 'comment_post' },\n });\n\n auditor?.createEvent({\n eventId: 'comment-post',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(updatedPost),\n comment: request.body.content,\n },\n });\n\n response.status(201).json(updatedPost);\n });\n\n // POST /posts/:id/comments/:commentId\n router.post(`/posts/:id/comments/:commentId`, async (request, response) => {\n // Validation\n // Act\n const postId = Number.parseInt(request.params.id, 10);\n const commentId = Number.parseInt(request.params.commentId, 10);\n if (Number.isNaN(postId) || Number.isNaN(commentId)) {\n response.status(400).send({ errors: 'Invalid id', type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const { post, username, answersFilter, commentsFilter, tagsFilter } = ret;\n\n if (post.status === 'obsolete') {\n response.status(400).send({\n errors: 'Cannot edit comments on obsolete posts',\n type: 'body',\n });\n return;\n }\n\n const comment = await database.getComment(commentId, { postId });\n\n if (!comment) {\n response.status(404).send({ errors: 'Comment not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditCommentPermission, resource: comment }],\n { throwOnDeny: true },\n );\n\n const updatedPost = await database.updatePostComment(\n postId,\n commentId,\n username,\n request.body.content,\n {\n tagsFilter,\n commentsFilter,\n answersFilter,\n },\n );\n\n if (updatedPost === null) {\n response\n .status(400)\n .send({ errors: 'Failed to update post comment', type: 'body' });\n return;\n }\n\n auditor?.createEvent({\n eventId: 'update-comment',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(updatedPost),\n from: entityToJsonObject(comment),\n to: request.body.content,\n },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // DELETE /posts/:id/comments/:commentId\n router.delete(`/posts/:id/comments/:commentId`, async (request, response) => {\n // Validation\n // Act\n const postId = Number.parseInt(request.params.id, 10);\n const commentId = Number.parseInt(request.params.commentId, 10);\n if (Number.isNaN(postId) || Number.isNaN(commentId)) {\n response.status(400).send({ errors: 'Invalid id', type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const { post, username, answersFilter, tagsFilter, commentsFilter } = ret;\n\n if (post.status === 'obsolete') {\n response.status(400).send({\n errors: 'Cannot delete comments on obsolete posts',\n type: 'body',\n });\n return;\n }\n\n const comment = await database.getComment(commentId, { postId });\n\n if (!comment) {\n response.status(404).send({ errors: 'Comment not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteCommentPermission, resource: comment }],\n { throwOnDeny: true },\n );\n\n let updatedPost = null;\n if (comment.status === 'deleted' || request.body?.permanent === true) {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(404)\n .send({ errors: 'Comment not found', type: 'query' });\n return;\n }\n updatedPost = await database.deletePostComment(\n postId,\n commentId,\n username,\n true,\n {\n tagsFilter,\n commentsFilter,\n answersFilter,\n },\n );\n } else {\n updatedPost = await database.deletePostComment(\n postId,\n commentId,\n username,\n false,\n {\n tagsFilter,\n commentsFilter,\n answersFilter,\n },\n );\n }\n\n if (updatedPost === null) {\n response\n .status(400)\n .send({ errors: 'Failed to delete post comment', type: 'body' });\n return;\n }\n\n auditor?.createEvent({\n eventId: 'delete-comment',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(updatedPost),\n comment: entityToJsonObject(comment),\n },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // POST /posts\n router.post(`/posts`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(PostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreatePostPermission }],\n { throwOnDeny: true },\n );\n\n const existingTags = await database.getTags();\n const [tags, entities, username, created] = await Promise.all([\n getTags(request, options, existingTags),\n getEntities(request, config),\n permissionMgr.getUsername(request),\n getCreated(request, options),\n ]);\n\n if (request.body.author && request.body.author !== username) {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n }\n\n // Act\n const post = await database.createPost({\n user_ref: username,\n title: request.body.title,\n content: request.body.content,\n author: request.body.author,\n created,\n tags,\n entities,\n images: request.body.images,\n anonymous: request.body.anonymous || username === 'user:default/guest',\n type: request.body.type,\n headerImage: request.body.headerImage,\n url: request.body.url,\n status: request.body.status || 'active',\n opts: {\n includeComments: false,\n includeVotes: false,\n includeAnswers: false,\n },\n });\n\n if (!post) {\n response.status(400).send({ errors: 'Failed to post', type: 'body' });\n return;\n }\n\n wrapAsync(async () => {\n if (!post || post.status !== 'active') {\n return;\n }\n const followingUsers = await Promise.all([\n database.getUsersForTags(tags),\n database.getUsersForEntities(entities),\n database.getFollowingUsers(username),\n database.getUsersWhoFavoritedPost(post.id),\n ]);\n const sent = await notificationMgr.onNewPost(\n username,\n post,\n followingUsers.flat(),\n );\n const mentions = findEntityMentions(request.body.content);\n if (mentions.length > 0) {\n await notificationMgr.onMention(username, post, mentions, sent);\n }\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'new_post' },\n });\n\n auditor?.createEvent({\n eventId: 'create-post',\n severityLevel: 'medium',\n request,\n meta: {\n post: entityToJsonObject(post),\n },\n });\n\n await mapAdditionalFields(request, [post], options, { username });\n\n // Response\n response.status(201).json(post);\n });\n\n // POST /posts/:id\n router.post(`/posts/:id`, async (request, response) => {\n // Validation\n\n const validateRequestBody = ajv.compile(PostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const {\n post: originalPost,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditPostPermission, resource: originalPost }],\n { throwOnDeny: true },\n );\n\n if (request.body.status !== 'active' && originalPost.status === 'active') {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n }\n\n if (\n request.body.author &&\n request.body.author !== username &&\n request.body.author !== originalPost.author\n ) {\n if (!(await permissionMgr.isModerator(request))) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n }\n\n const existingTags = await database.getTags();\n const [tags, entities] = await Promise.all([\n getTags(request, options, existingTags),\n getEntities(request, config),\n ]);\n\n // Act\n const post = await database.updatePost({\n id: postId,\n user_ref: username,\n author: request.body.author,\n title: request.body.title,\n content: request.body.content,\n tags,\n entities,\n images: request.body.images,\n headerImage: request.body.headerImage,\n url: request.body.url,\n status: request.body.status || 'active',\n setUpdatedBy: originalPost.status !== 'draft',\n opts: { tagsFilter, commentsFilter, answersFilter },\n });\n\n if (!post) {\n response.sendStatus(401);\n return;\n }\n\n wrapAsync(async () => {\n if (!post || post.status !== 'active') {\n return;\n }\n const newTags = tags.filter(t => !originalPost.tags?.includes(t));\n const newEntities = entities.filter(\n e => !originalPost.entities?.includes(e),\n );\n\n const followingUsers = await Promise.all([\n database.getUsersForTags(newTags),\n database.getUsersForEntities(newEntities),\n ]);\n\n const sent = await notificationMgr.onPostEdit(\n username,\n post,\n followingUsers.flat(),\n );\n const originalMentions = findEntityMentions(originalPost.content);\n const mentions = findEntityMentions(request.body.content);\n const newMentions = mentions.filter(m => !originalMentions.includes(m));\n\n if (newMentions.length > 0) {\n await notificationMgr.onMention(username, post, newMentions, sent);\n }\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'update_post' },\n });\n\n await mapAdditionalFields(request, [post], options, { username });\n\n auditor?.createEvent({\n eventId: 'update-post',\n severityLevel: 'medium',\n request,\n meta: {\n from: entityToJsonObject(originalPost),\n to: entityToJsonObject(post),\n },\n });\n\n // Response\n response.json(post);\n });\n\n // DELETE /posts/:id\n router.delete('/posts/:id', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: 'Invalid data', type: 'body' });\n return;\n }\n\n const { post, username } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeletePostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n let deleted = false;\n if (post.status === 'deleted' || request.body?.permanent === true) {\n if (!(await permissionMgr.isModerator(request))) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n deleted = await database.deletePost(post.id, true);\n } else {\n deleted = await database.deletePost(post.id);\n if (deleted) {\n notificationMgr.onPostDelete(username, post, request.body.reason);\n }\n }\n\n if (deleted) {\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: post.author,\n reason: request.body.reason,\n },\n metadata: { action: 'delete_post' },\n });\n\n auditor?.createEvent({\n eventId: 'delete-post',\n severityLevel: 'medium',\n request,\n meta: { post: entityToJsonObject(post), reason: request.body.reason },\n });\n }\n\n response.sendStatus(deleted ? 204 : 404);\n });\n\n const votePost = async (\n request: Request<any>,\n response: Response,\n score: number,\n ) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n if (post.own) {\n response\n .status(400)\n .send({ errors: 'You cannot vote your own post', type: 'body' });\n return;\n }\n\n const voted = await database.votePost(username, postId, score);\n\n if (!voted) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n const resp = await database.getPost(username, postId, false, {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeTags: false,\n includeEntities: false,\n });\n if (resp === null) {\n response.sendStatus(404);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n resp,\n author: username,\n score,\n },\n metadata: { action: 'vote_post' },\n });\n\n await mapAdditionalFields(request, [resp], options, { username });\n resp.ownVote = score;\n\n auditor?.createEvent({\n eventId: 'vote',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(post), score },\n });\n\n signalPostStats(signals, resp);\n\n // Response\n response.json(resp);\n };\n\n // POST /posts/:id/restore\n router.post('/posts/:id/restore', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response, false, true);\n if (!ret) return;\n\n if (!(await permissionMgr.isModerator(request))) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n const {\n post: originalPost,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n // Act\n const post = await database.updatePost({\n id: postId,\n status: 'active',\n user_ref: username,\n setUpdatedBy: false,\n opts: { tagsFilter, commentsFilter, answersFilter },\n });\n\n if (!post) {\n response.sendStatus(401);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'restore_post' },\n });\n\n await mapAdditionalFields(request, [post], options, { username });\n\n auditor?.createEvent({\n eventId: 'restore-post',\n severityLevel: 'medium',\n request,\n meta: {\n from: entityToJsonObject(originalPost),\n to: entityToJsonObject(post),\n },\n });\n\n // Response\n response.json(post);\n });\n\n // PUT /posts/:id/click\n router.put('/posts/:id/click', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n const { postId, username } = ret;\n await database.clickPost(username, postId);\n\n const resp = await database.getPost(username, postId, false, {\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeTags: false,\n includeEntities: false,\n });\n\n if (!resp) {\n response.status(404).send({ errors: 'Post not found', type: 'query' });\n return;\n }\n\n signalPostStats(signals, resp);\n response.status(200).send({});\n });\n\n // GET /posts/:id/upvote\n router.get(`/posts/:id/upvote`, async (request, response) => {\n return await votePost(request, response, 1);\n });\n\n // GET /posts/:id/downvote\n router.get(`/posts/:id/downvote`, async (request, response) => {\n return await votePost(request, response, -1);\n });\n\n router.delete('/posts/:id/vote', async (request, response) => {\n // Validation\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n const deleted = await database.deletePostVote(username, postId);\n if (!deleted) {\n response.sendStatus(404);\n return;\n }\n\n const resp = await database.getPost(username, postId, false, {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeAttachments: false,\n includeTags: false,\n includeEntities: false,\n });\n\n if (resp === null) {\n response.sendStatus(404);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n post,\n author: username,\n },\n metadata: { action: 'delete_vote' },\n });\n\n await mapAdditionalFields(request, [resp], options, { username });\n resp.ownVote = undefined;\n\n signalPostStats(signals, resp);\n\n auditor?.createEvent({\n eventId: 'delete-vote',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(post) },\n });\n response.json(resp);\n });\n\n // POST /posts/:id/review\n router.post('/posts/:id/review', async (request, response) => {\n const validateRequestBody = ajv.compile(PostReviewBodySchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const { post, postId } = ret;\n\n const user = await options.permissionMgr.getUsername(request, true);\n\n await options.permissionMgr.authorize(\n request,\n [\n { permission: qetaReadPostPermission, resource: post },\n { permission: qetaCreatePostReviewPermission },\n ],\n { throwOnDeny: true },\n );\n\n const updatedPost = await options.database.reviewPost(\n user,\n postId,\n request.body.status,\n request.body.comment,\n );\n if (!updatedPost) {\n response.sendStatus(404);\n return;\n }\n response.json(updatedPost);\n });\n\n // GET /posts/:id/reviews\n router.get('/posts/:id/reviews', async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const { post, postId } = ret;\n\n await options.permissionMgr.authorize(\n request,\n [\n { permission: qetaReadPostPermission, resource: post },\n { permission: qetaReadPostReviewPermission },\n ],\n { throwOnDeny: true },\n );\n\n const reviews = await options.database.getPostReviews(postId);\n response.json(reviews);\n });\n\n // GET /posts/:id/favorite\n router.get(`/posts/:id/favorite`, async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n const favorited = await database.favoritePost(username, postId);\n\n if (!favorited) {\n response.sendStatus(404);\n return;\n }\n\n const updatedPost = await database.getPost(\n username,\n Number.parseInt(request.params.id, 10),\n false,\n {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeEntities: false,\n includeVotes: false,\n includeTags: false,\n includeAttachments: false,\n },\n );\n\n if (!updatedPost) {\n response.sendStatus(404);\n return;\n }\n\n auditor?.createEvent({\n eventId: 'favorite-post',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(updatedPost) },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // GET /posts/:id/unfavorite\n router.get(`/posts/:id/unfavorite`, async (request, response) => {\n const ret = await getPostAndCheckStatus(request, response);\n if (!ret) return;\n const {\n post,\n postId,\n username,\n answersFilter,\n tagsFilter,\n commentsFilter,\n } = ret;\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadPostPermission, resource: post }],\n { throwOnDeny: true },\n );\n\n const unfavorited = await database.unfavoritePost(username, postId);\n\n if (!unfavorited) {\n response.sendStatus(404);\n return;\n }\n\n const updatedPost = await database.getPost(\n username,\n Number.parseInt(request.params.id, 10),\n false,\n {\n answersFilter,\n tagsFilter,\n commentsFilter,\n includeComments: false,\n includeAnswers: false,\n includeEntities: false,\n includeVotes: false,\n includeTags: false,\n includeAttachments: false,\n },\n );\n\n if (!updatedPost) {\n response.sendStatus(404);\n return;\n }\n\n auditor?.createEvent({\n eventId: 'unfavorite-post',\n severityLevel: 'low',\n request,\n meta: { post: entityToJsonObject(updatedPost) },\n });\n\n await mapAdditionalFields(request, [updatedPost], options, { username });\n\n // Response\n response.json(updatedPost);\n });\n\n // POST /url\n router.post(`/url`, async (request, response) => {\n const validateQuery = ajv.compile(URLMetadataSchema);\n if (!validateQuery(request.body)) {\n response.status(400).send({ errors: validateQuery.errors, type: 'body' });\n return;\n }\n\n const url = new URL(request.body.url);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n response\n .status(400)\n .send({ errors: 'Invalid URL protocol', type: 'url' });\n return;\n }\n if (url.hostname === 'localhost') {\n response\n .status(400)\n .send({ errors: 'localhost not allowed', type: 'url' });\n return;\n }\n\n const cacheKey = `url:metadata:${url.toString()}`;\n const cached = await cache?.get(cacheKey);\n if (cached) {\n response.json(cached);\n return;\n }\n\n const metadata = await extractMetadata(url, options.logger);\n await cache?.set(cacheKey, metadata, { ttl: { weeks: 2 } });\n response.json(metadata);\n });\n};\n"],"names":["Ajv","addFormats","durationToMilliseconds","qetaReadPostPermission","qetaReadTagPermission","qetaReadCommentPermission","qetaReadAnswerPermission","signalPostStats","PostsQuerySchema","validateDateRange","mapAdditionalFields","getCachedData","PostQuerySchema","entityToJsonObject","getCreated","CommentSchema","qetaCreateCommentPermission","wrapAsync","findEntityMentions","qetaEditCommentPermission","qetaDeleteCommentPermission","PostSchema","qetaCreatePostPermission","getTags","getEntities","qetaEditPostPermission","DeleteMetadataSchema","qetaDeletePostPermission","PostReviewBodySchema","qetaCreatePostReviewPermission","qetaReadPostReviewPermission","URLMetadataSchema","extractMetadata"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../src/service/types.ts"],"sourcesContent":["import { JSONSchemaType } from 'ajv';\nimport { QetaStore } from '../database/QetaStore';\nimport {\n AuditorService,\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n PermissionsRegistryService,\n PermissionsService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { EventsService } from '@backstage/plugin-events-node';\nimport { SignalsService } from '@backstage/plugin-signals-node';\nimport { NotificationService } from '@backstage/plugin-notifications-node';\nimport { NotificationManager } from './NotificationManager';\nimport {\n AIQuery,\n AnswersQuery,\n CollectionsQuery,\n EntitiesQuery,\n PostQuery,\n PostsQuery,\n PostStatus,\n PostType,\n SuggestionsQuery,\n TagsQuery,\n URLMetadataQuery,\n UsersQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { AIHandler } from '@drodil/backstage-plugin-qeta-node';\nimport { PermissionManager } from './PermissionManager.ts';\n\nexport interface RouterOptions {\n database: QetaStore;\n logger: LoggerService;\n config: Config;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n catalog: CatalogApi;\n auth: AuthService;\n cache?: CacheService;\n permissions?: PermissionsService;\n events?: EventsService;\n signals?: SignalsService;\n notifications?: NotificationService;\n aiHandler?: AIHandler;\n permissionsRegistry?: PermissionsRegistryService;\n auditor?: AuditorService;\n notificationMgr: NotificationManager;\n}\n\nexport interface RouteOptions extends RouterOptions {\n notificationMgr: NotificationManager;\n permissionMgr: PermissionManager;\n}\n\nexport interface PostContent {\n title: string;\n content: string;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n user?: string;\n created?: string;\n headerImage?: string;\n url?: string;\n anonymous?: boolean;\n type: PostType;\n status?: PostStatus;\n}\n\nexport interface TemplateContent {\n title: string;\n description: string;\n questionTitle?: string;\n questionContent?: string;\n tags?: string[];\n entities?: string[];\n}\n\nexport interface CollectionContent {\n title: string;\n description?: string;\n headerImage?: string;\n images?: number[];\n created?: string;\n tags?: string[];\n entities?: string[];\n users?: string[];\n}\n\nexport interface CollectionPostContent {\n postId: number;\n}\n\nexport interface CollectionRankContent {\n postId: number;\n rank: 'top' | 'bottom' | 'up' | 'down';\n}\n\nexport const CollectionsQuerySchema: JSONSchemaType<CollectionsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n searchQuery: { type: 'string', nullable: true },\n owner: { type: 'string', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'created',\n 'title',\n 'postsCount',\n 'questionsCount',\n 'articlesCount',\n 'linksCount',\n 'followerCount',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n entitiesRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n includePosts: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n tagsRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n fromDate: { type: 'string', nullable: true, format: 'date' },\n toDate: { type: 'string', nullable: true, format: 'date' },\n ids: { type: 'array', items: { type: 'integer' }, nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const PostsQuerySchema: JSONSchemaType<PostsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n author: { type: 'string', nullable: true },\n excludeAuthors: {\n type: 'array',\n items: { type: 'string' },\n nullable: true,\n },\n orderBy: {\n type: 'string',\n enum: [\n 'rank',\n 'views',\n 'title',\n 'trend',\n 'score',\n 'answersCount',\n 'created',\n 'updated',\n ],\n nullable: true,\n },\n collectionId: { type: 'number', nullable: true },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n noCorrectAnswer: { type: 'boolean', nullable: true },\n noAnswers: { type: 'boolean', nullable: true },\n hasAnswers: { type: 'boolean', nullable: true },\n favorite: { type: 'boolean', nullable: true },\n noVotes: { type: 'boolean', nullable: true },\n status: {\n type: 'string',\n enum: ['active', 'draft', 'deleted'],\n nullable: true,\n },\n random: { type: 'boolean', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n entitiesRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n tagsRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n includeAnswers: { type: 'boolean', nullable: true },\n includeVotes: { type: 'boolean', nullable: true },\n includeAttachments: { type: 'boolean', nullable: true },\n includeHealth: { type: 'boolean', nullable: true },\n reviewNeeded: { type: 'boolean', nullable: true },\n obsolete: { type: 'boolean', nullable: true },\n includeTags: { type: 'boolean', nullable: true },\n includeEntities: { type: 'boolean', nullable: true },\n includeTrend: { type: 'boolean', nullable: true },\n includeComments: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n searchQuery: { type: 'string', nullable: true },\n fromDate: { type: 'string', nullable: true, format: 'date' },\n toDate: { type: 'string', nullable: true, format: 'date' },\n type: {\n type: 'string',\n enum: ['question', 'article', 'link'],\n nullable: true,\n },\n ids: { type: 'array', items: { type: 'integer' }, nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const PostQuerySchema: JSONSchemaType<PostQuery> = {\n type: 'object',\n properties: {\n anonymous: { type: 'boolean', nullable: true },\n },\n};\n\nexport const TagsQuerySchema: JSONSchemaType<TagsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'tag',\n 'postsCount',\n 'questionsCount',\n 'articlesCount',\n 'linksCount',\n 'followerCount',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n searchQuery: { type: 'string', nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const UsersQuerySchema: JSONSchemaType<UsersQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'userRef',\n 'totalPosts',\n 'totalQuestions',\n 'totalAnswers',\n 'totalArticles',\n 'totalLinks',\n 'totalViews',\n 'totalVotes',\n 'followerCount',\n 'reputation',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n searchQuery: { type: 'string', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const EntitiesQuerySchema: JSONSchemaType<EntitiesQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'entityRef',\n 'postsCount',\n 'questionsCount',\n 'articlesCount',\n 'linksCount',\n 'followerCount',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n searchQuery: { type: 'string', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const AnswersQuerySchema: JSONSchemaType<AnswersQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n author: { type: 'string', nullable: true },\n orderBy: {\n type: 'string',\n enum: ['score', 'created', 'updated'],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n noCorrectAnswer: { type: 'boolean', nullable: true },\n noVotes: { type: 'boolean', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n entitiesRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n tagsRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n includeVotes: { type: 'boolean', nullable: true },\n includeEntities: { type: 'boolean', nullable: true },\n includeComments: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n searchQuery: { type: 'string', nullable: true },\n fromDate: { type: 'string', nullable: true, format: 'date' },\n toDate: { type: 'string', nullable: true, format: 'date' },\n ids: { type: 'array', items: { type: 'integer' }, nullable: true },\n questionId: { type: 'integer', nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const PostSchema: JSONSchemaType<PostContent> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n content: { type: 'string', minLength: 0 },\n author: { type: 'string', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n images: { type: 'array', items: { type: 'integer' }, nullable: true },\n user: { type: 'string', minLength: 1, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n anonymous: { type: 'boolean', nullable: true },\n headerImage: { type: 'string', nullable: true },\n url: { type: 'string', nullable: true },\n type: { type: 'string', enum: ['question', 'article', 'link'] },\n status: {\n type: 'string',\n enum: ['active', 'draft', 'deleted'],\n nullable: true,\n },\n },\n required: ['title', 'content'],\n additionalProperties: false,\n};\n\nexport const TemplateSchema: JSONSchemaType<TemplateContent> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n description: { type: 'string', minLength: 1 },\n questionTitle: { type: 'string', nullable: true },\n questionContent: { type: 'string', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n },\n required: ['title', 'description'],\n additionalProperties: false,\n};\n\nexport const CollectionSchema: JSONSchemaType<CollectionContent> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n description: { type: 'string', nullable: true },\n headerImage: { type: 'string', nullable: true },\n images: { type: 'array', items: { type: 'integer' }, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n users: { type: 'array', items: { type: 'string' }, nullable: true },\n },\n required: ['title'],\n additionalProperties: false,\n};\n\nexport const CollectionPostSchema: JSONSchemaType<CollectionPostContent> = {\n type: 'object',\n properties: {\n postId: { type: 'integer' },\n },\n required: ['postId'],\n additionalProperties: false,\n};\n\nexport const CollectionRankPostSchema: JSONSchemaType<CollectionRankContent> = {\n type: 'object',\n properties: {\n postId: { type: 'integer' },\n rank: { type: 'string', enum: ['top', 'bottom', 'up', 'down'] },\n },\n required: ['postId', 'rank'],\n additionalProperties: false,\n};\n\nexport interface AnswerQuestion {\n answer: string;\n images?: number[];\n user?: string;\n author?: string;\n created?: string;\n anonymous?: boolean;\n}\n\nexport const PostAnswerSchema: JSONSchemaType<AnswerQuestion> = {\n type: 'object',\n properties: {\n answer: { type: 'string', minLength: 1 },\n images: { type: 'array', items: { type: 'integer' }, nullable: true },\n user: { type: 'string', minLength: 1, nullable: true },\n author: { type: 'string', minLength: 1, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n anonymous: { type: 'boolean', nullable: true },\n },\n required: ['answer'],\n additionalProperties: false,\n};\n\nexport interface DeleteMetadata {\n reason?: string;\n permanent?: boolean;\n}\n\nexport const DeleteMetadataSchema: JSONSchemaType<DeleteMetadata> = {\n type: 'object',\n properties: {\n reason: { type: 'string', minLength: 1, nullable: true },\n permanent: { type: 'boolean', nullable: true },\n },\n additionalProperties: false,\n};\n\nexport interface Comment {\n content: string;\n user?: string;\n created?: string;\n}\n\nexport const CommentSchema: JSONSchemaType<Comment> = {\n type: 'object',\n properties: {\n content: { type: 'string', minLength: 1 },\n user: { type: 'string', minLength: 1, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n },\n required: ['content'],\n additionalProperties: false,\n};\n\nexport interface DraftQuestion {\n title: string;\n content: string;\n tags?: string[];\n entities?: string[];\n}\n\nexport const DraftQuestionSchema: JSONSchemaType<DraftQuestion> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n content: { type: 'string', minLength: 1 },\n tags: {\n type: 'array',\n items: { type: 'string' },\n nullable: true,\n },\n entities: {\n type: 'array',\n items: { type: 'string' },\n nullable: true,\n },\n },\n required: ['title', 'content'],\n additionalProperties: false,\n};\n\nexport const AIQuerySchema: JSONSchemaType<AIQuery> = {\n type: 'object',\n properties: {\n regenerate: { type: 'boolean', default: false, nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const SuggestionsQuerySchema: JSONSchemaType<SuggestionsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', minimum: 1, nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport interface File {\n name: string;\n path: string;\n buffer: Buffer;\n mimeType: string;\n ext: string;\n size: number;\n}\n\nexport const URLMetadataSchema: JSONSchemaType<URLMetadataQuery> = {\n type: 'object',\n properties: {\n url: { type: 'string', minLength: 7 }, // http://\n },\n required: ['url'],\n additionalProperties: false,\n};\n\nexport interface PostReviewBody {\n status: 'valid' | 'obsolete';\n comment?: string;\n}\n\nexport const PostReviewBodySchema: JSONSchemaType<PostReviewBody> = {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['valid', 'obsolete'] },\n comment: { type: 'string', nullable: true },\n },\n required: ['status'],\n additionalProperties: false,\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../src/service/types.ts"],"sourcesContent":["import { JSONSchemaType } from 'ajv';\nimport { QetaStore } from '../database/QetaStore';\nimport {\n AuditorService,\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n PermissionsRegistryService,\n PermissionsService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { EventsService } from '@backstage/plugin-events-node';\nimport { SignalsService } from '@backstage/plugin-signals-node';\nimport { NotificationService } from '@backstage/plugin-notifications-node';\nimport { NotificationManager } from './NotificationManager';\nimport {\n AIQuery,\n AnswersQuery,\n CollectionsQuery,\n EntitiesQuery,\n PostQuery,\n PostsQuery,\n PostStatus,\n PostType,\n SuggestionsQuery,\n TagsQuery,\n URLMetadataQuery,\n UsersQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { AIHandler } from '@drodil/backstage-plugin-qeta-node';\nimport { PermissionManager } from './PermissionManager.ts';\n\nexport interface RouterOptions {\n database: QetaStore;\n logger: LoggerService;\n config: Config;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n catalog: CatalogApi;\n auth: AuthService;\n cache?: CacheService;\n permissions?: PermissionsService;\n events?: EventsService;\n signals?: SignalsService;\n notifications?: NotificationService;\n aiHandler?: AIHandler;\n permissionsRegistry?: PermissionsRegistryService;\n auditor?: AuditorService;\n notificationMgr: NotificationManager;\n}\n\nexport interface RouteOptions extends RouterOptions {\n notificationMgr: NotificationManager;\n permissionMgr: PermissionManager;\n}\n\nexport interface PostContent {\n title: string;\n content: string;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n user?: string;\n created?: string;\n headerImage?: string;\n url?: string;\n anonymous?: boolean;\n type: PostType;\n status?: PostStatus;\n}\n\nexport interface TemplateContent {\n title: string;\n description: string;\n questionTitle?: string;\n questionContent?: string;\n tags?: string[];\n entities?: string[];\n}\n\nexport interface CollectionContent {\n title: string;\n description?: string;\n headerImage?: string;\n images?: number[];\n created?: string;\n tags?: string[];\n entities?: string[];\n users?: string[];\n}\n\nexport interface CollectionPostContent {\n postId: number;\n}\n\nexport interface CollectionRankContent {\n postId: number;\n rank: 'top' | 'bottom' | 'up' | 'down';\n}\n\nexport const CollectionsQuerySchema: JSONSchemaType<CollectionsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n searchQuery: { type: 'string', nullable: true },\n owner: { type: 'string', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'created',\n 'title',\n 'postsCount',\n 'questionsCount',\n 'articlesCount',\n 'linksCount',\n 'followerCount',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n entitiesRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n includePosts: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n tagsRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n fromDate: { type: 'string', nullable: true, format: 'date' },\n toDate: { type: 'string', nullable: true, format: 'date' },\n ids: { type: 'array', items: { type: 'integer' }, nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const PostsQuerySchema: JSONSchemaType<PostsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n author: { type: 'string', nullable: true },\n excludeAuthors: {\n type: 'array',\n items: { type: 'string' },\n nullable: true,\n },\n orderBy: {\n type: 'string',\n enum: [\n 'rank',\n 'views',\n 'title',\n 'trend',\n 'score',\n 'answersCount',\n 'created',\n 'updated',\n ],\n nullable: true,\n },\n collectionId: { type: 'number', nullable: true },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n noCorrectAnswer: { type: 'boolean', nullable: true },\n noAnswers: { type: 'boolean', nullable: true },\n hasAnswers: { type: 'boolean', nullable: true },\n favorite: { type: 'boolean', nullable: true },\n noVotes: { type: 'boolean', nullable: true },\n status: {\n type: 'string',\n enum: ['active', 'draft', 'deleted'],\n nullable: true,\n },\n random: { type: 'boolean', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n entitiesRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n tagsRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n includeAnswers: { type: 'boolean', nullable: true },\n includeVotes: { type: 'boolean', nullable: true },\n includeAttachments: { type: 'boolean', nullable: true },\n includeHealth: { type: 'boolean', nullable: true },\n reviewNeeded: { type: 'boolean', nullable: true },\n obsolete: { type: 'boolean', nullable: true },\n includeTags: { type: 'boolean', nullable: true },\n includeEntities: { type: 'boolean', nullable: true },\n includeTrend: { type: 'boolean', nullable: true },\n includeComments: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n searchQuery: { type: 'string', nullable: true },\n fromDate: { type: 'string', nullable: true, format: 'date' },\n toDate: { type: 'string', nullable: true, format: 'date' },\n type: {\n type: 'string',\n enum: ['question', 'article', 'link'],\n nullable: true,\n },\n ids: { type: 'array', items: { type: 'integer' }, nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const PostQuerySchema: JSONSchemaType<PostQuery> = {\n type: 'object',\n properties: {\n anonymous: { type: 'boolean', nullable: true },\n },\n};\n\nexport const TagsQuerySchema: JSONSchemaType<TagsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'tag',\n 'postsCount',\n 'questionsCount',\n 'articlesCount',\n 'linksCount',\n 'followerCount',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n searchQuery: { type: 'string', nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const UsersQuerySchema: JSONSchemaType<UsersQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'userRef',\n 'totalPosts',\n 'totalQuestions',\n 'totalAnswers',\n 'totalArticles',\n 'totalLinks',\n 'totalViews',\n 'totalVotes',\n 'followerCount',\n 'reputation',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n searchQuery: { type: 'string', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const EntitiesQuerySchema: JSONSchemaType<EntitiesQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n orderBy: {\n type: 'string',\n enum: [\n 'entityRef',\n 'postsCount',\n 'questionsCount',\n 'articlesCount',\n 'linksCount',\n 'followerCount',\n ],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n searchQuery: { type: 'string', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const AnswersQuerySchema: JSONSchemaType<AnswersQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', nullable: true },\n offset: { type: 'integer', nullable: true },\n author: { type: 'string', nullable: true },\n orderBy: {\n type: 'string',\n enum: ['score', 'created', 'updated'],\n nullable: true,\n },\n order: { type: 'string', enum: ['desc', 'asc'], nullable: true },\n noCorrectAnswer: { type: 'boolean', nullable: true },\n noVotes: { type: 'boolean', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n entitiesRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n tagsRelation: { type: 'string', enum: ['and', 'or'], nullable: true },\n includeVotes: { type: 'boolean', nullable: true },\n includeEntities: { type: 'boolean', nullable: true },\n includeComments: { type: 'boolean', nullable: true },\n includeExperts: { type: 'boolean', nullable: true },\n searchQuery: { type: 'string', nullable: true },\n fromDate: { type: 'string', nullable: true, format: 'date' },\n toDate: { type: 'string', nullable: true, format: 'date' },\n ids: { type: 'array', items: { type: 'integer' }, nullable: true },\n questionId: { type: 'integer', nullable: true },\n checkAccess: { type: 'boolean', nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const PostSchema: JSONSchemaType<PostContent> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n content: { type: 'string', minLength: 0 },\n author: { type: 'string', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n images: { type: 'array', items: { type: 'integer' }, nullable: true },\n user: { type: 'string', minLength: 1, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n anonymous: { type: 'boolean', nullable: true },\n headerImage: { type: 'string', nullable: true },\n url: { type: 'string', nullable: true },\n type: { type: 'string', enum: ['question', 'article', 'link'] },\n status: {\n type: 'string',\n enum: ['active', 'draft', 'deleted'],\n nullable: true,\n },\n },\n required: ['title', 'content'],\n additionalProperties: false,\n};\n\nexport const TemplateSchema: JSONSchemaType<TemplateContent> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n description: { type: 'string', minLength: 1 },\n questionTitle: { type: 'string', nullable: true },\n questionContent: { type: 'string', nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n },\n required: ['title', 'description'],\n additionalProperties: false,\n};\n\nexport const CollectionSchema: JSONSchemaType<CollectionContent> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n description: { type: 'string', nullable: true },\n headerImage: { type: 'string', nullable: true },\n images: { type: 'array', items: { type: 'integer' }, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n tags: { type: 'array', items: { type: 'string' }, nullable: true },\n entities: { type: 'array', items: { type: 'string' }, nullable: true },\n users: { type: 'array', items: { type: 'string' }, nullable: true },\n },\n required: ['title'],\n additionalProperties: false,\n};\n\nexport const CollectionPostSchema: JSONSchemaType<CollectionPostContent> = {\n type: 'object',\n properties: {\n postId: { type: 'integer' },\n },\n required: ['postId'],\n additionalProperties: false,\n};\n\nexport const CollectionRankPostSchema: JSONSchemaType<CollectionRankContent> = {\n type: 'object',\n properties: {\n postId: { type: 'integer' },\n rank: { type: 'string', enum: ['top', 'bottom', 'up', 'down'] },\n },\n required: ['postId', 'rank'],\n additionalProperties: false,\n};\n\nexport interface AnswerQuestion {\n answer: string;\n images?: number[];\n user?: string;\n author?: string;\n created?: string;\n anonymous?: boolean;\n}\n\nexport const PostAnswerSchema: JSONSchemaType<AnswerQuestion> = {\n type: 'object',\n properties: {\n answer: { type: 'string', minLength: 1 },\n images: { type: 'array', items: { type: 'integer' }, nullable: true },\n user: { type: 'string', minLength: 1, nullable: true },\n author: { type: 'string', minLength: 1, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n anonymous: { type: 'boolean', nullable: true },\n },\n required: ['answer'],\n additionalProperties: false,\n};\n\nexport interface DeleteMetadata {\n reason?: string;\n permanent?: boolean;\n}\n\nexport const DeleteMetadataSchema: JSONSchemaType<DeleteMetadata> = {\n type: 'object',\n properties: {\n reason: { type: 'string', minLength: 1, nullable: true },\n permanent: { type: 'boolean', nullable: true },\n },\n additionalProperties: false,\n};\n\nexport interface Comment {\n content: string;\n user?: string;\n created?: string;\n}\n\nexport const CommentSchema: JSONSchemaType<Comment> = {\n type: 'object',\n properties: {\n content: { type: 'string', minLength: 1 },\n user: { type: 'string', minLength: 1, nullable: true },\n created: { type: 'string', minLength: 1, nullable: true },\n },\n required: ['content'],\n additionalProperties: false,\n};\n\nexport interface DraftQuestion {\n title: string;\n content: string;\n tags?: string[];\n entities?: string[];\n limit?: number;\n}\n\nexport const DraftQuestionSchema: JSONSchemaType<DraftQuestion> = {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n content: { type: 'string', minLength: 1 },\n tags: {\n type: 'array',\n items: { type: 'string' },\n nullable: true,\n },\n entities: {\n type: 'array',\n items: { type: 'string' },\n nullable: true,\n },\n limit: {\n type: 'number',\n minimum: 1,\n nullable: true,\n },\n },\n required: ['title', 'content'],\n additionalProperties: false,\n};\n\nexport const AIQuerySchema: JSONSchemaType<AIQuery> = {\n type: 'object',\n properties: {\n regenerate: { type: 'boolean', default: false, nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport const SuggestionsQuerySchema: JSONSchemaType<SuggestionsQuery> = {\n type: 'object',\n properties: {\n limit: { type: 'integer', minimum: 1, nullable: true },\n },\n required: [],\n additionalProperties: false,\n};\n\nexport interface File {\n name: string;\n path: string;\n buffer: Buffer;\n mimeType: string;\n ext: string;\n size: number;\n}\n\nexport const URLMetadataSchema: JSONSchemaType<URLMetadataQuery> = {\n type: 'object',\n properties: {\n url: { type: 'string', minLength: 7 }, // http://\n },\n required: ['url'],\n additionalProperties: false,\n};\n\nexport interface PostReviewBody {\n status: 'valid' | 'obsolete';\n comment?: string;\n}\n\nexport const PostReviewBodySchema: JSONSchemaType<PostReviewBody> = {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['valid', 'obsolete'] },\n comment: { type: 'string', nullable: true },\n },\n required: ['status'],\n additionalProperties: false,\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drodil/backstage-plugin-qeta-backend",
|
|
3
|
-
"version": "3.55.
|
|
3
|
+
"version": "3.55.3",
|
|
4
4
|
"description": "Backstage.io Q&A plugin backend",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backstage",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"@backstage/plugin-permission-node": "^0.10.7",
|
|
67
67
|
"@backstage/plugin-signals-node": "^0.1.27",
|
|
68
68
|
"@backstage/types": "^1.2.2",
|
|
69
|
-
"@drodil/backstage-plugin-qeta-common": "^3.55.
|
|
70
|
-
"@drodil/backstage-plugin-qeta-node": "^3.55.
|
|
69
|
+
"@drodil/backstage-plugin-qeta-common": "^3.55.3",
|
|
70
|
+
"@drodil/backstage-plugin-qeta-node": "^3.55.3",
|
|
71
71
|
"@smithy/node-http-handler": "^4.0.2",
|
|
72
72
|
"@types/express": "*",
|
|
73
73
|
"@types/mime-types": "^2.1.4",
|
|
@@ -105,9 +105,10 @@
|
|
|
105
105
|
"@backstage/plugin-search-backend-module-pg": "^0.5.51",
|
|
106
106
|
"@backstage/plugin-signals-backend": "^0.3.11",
|
|
107
107
|
"@backstage/plugin-techdocs-backend": "^2.1.3",
|
|
108
|
-
"@
|
|
109
|
-
"@drodil/backstage-plugin-
|
|
110
|
-
"@drodil/backstage-plugin-
|
|
108
|
+
"@backstage/plugin-user-settings-backend": "^0.3.9",
|
|
109
|
+
"@drodil/backstage-plugin-catalog-backend-module-qeta": "^3.55.3",
|
|
110
|
+
"@drodil/backstage-plugin-qeta-backend-module-openai": "^3.55.3",
|
|
111
|
+
"@drodil/backstage-plugin-search-backend-module-qeta": "^3.55.3",
|
|
111
112
|
"@types/sanitize-html": "^2.9.5",
|
|
112
113
|
"@types/stopword": "^2.0.3",
|
|
113
114
|
"@types/supertest": "^2.0.12",
|