diff --git a/src/posts/create.js b/src/posts/create.js index d541564c2e..224441c8df 100644 --- a/src/posts/create.js +++ b/src/posts/create.js @@ -1,94 +1,138 @@ -'use strict'; - -const _ = require('lodash'); - -const meta = require('../meta'); -const db = require('../database'); -const plugins = require('../plugins'); -const user = require('../user'); -const topics = require('../topics'); -const categories = require('../categories'); -const groups = require('../groups'); -const privileges = require('../privileges'); - -module.exports = function (Posts) { - Posts.create = async function (data) { - // This is an internal method, consider using Topics.reply instead - const { uid } = data; - const { tid } = data; - const content = data.content.toString(); - const timestamp = data.timestamp || Date.now(); - const isMain = data.isMain || false; - - if (!uid && parseInt(uid, 10) !== 0) { - throw new Error('[[error:invalid-uid]]'); - } - - if (data.toPid) { - await checkToPid(data.toPid, uid); - } - - const pid = await db.incrObjectField('global', 'nextPid'); - let postData = { - pid: pid, - uid: uid, - tid: tid, - content: content, - timestamp: timestamp, - }; - - if (data.toPid) { - postData.toPid = data.toPid; - } - if (data.ip && meta.config.trackIpPerPost) { - postData.ip = data.ip; - } - if (data.handle && !parseInt(uid, 10)) { - postData.handle = data.handle; - } - - let result = await plugins.hooks.fire('filter:post.create', { post: postData, data: data }); - postData = result.post; - await db.setObject(`post:${postData.pid}`, postData); - - const topicData = await topics.getTopicFields(tid, ['cid', 'pinned']); - postData.cid = topicData.cid; - - await Promise.all([ - db.sortedSetAdd('posts:pid', timestamp, postData.pid), - db.incrObjectField('global', 'postCount'), - user.onNewPostMade(postData), - topics.onNewPostMade(postData), - categories.onNewPostMade(topicData.cid, topicData.pinned, postData), - groups.onNewPostMade(postData), - addReplyTo(postData, timestamp), - Posts.uploads.sync(postData.pid), - ]); - - result = await plugins.hooks.fire('filter:post.get', { post: postData, uid: data.uid }); - result.post.isMain = isMain; - plugins.hooks.fire('action:post.save', { post: _.clone(result.post) }); - return result.post; - }; - - async function addReplyTo(postData, timestamp) { - if (!postData.toPid) { - return; - } - await Promise.all([ - db.sortedSetAdd(`pid:${postData.toPid}:replies`, timestamp, postData.pid), - db.incrObjectField(`post:${postData.toPid}`, 'replies'), - ]); - } - - async function checkToPid(toPid, uid) { - const [toPost, canViewToPid] = await Promise.all([ - Posts.getPostFields(toPid, ['pid', 'deleted']), - privileges.posts.can('posts:view_deleted', toPid, uid), - ]); - const toPidExists = !!toPost.pid; - if (!toPidExists || (toPost.deleted && !canViewToPid)) { - throw new Error('[[error:invalid-pid]]'); - } - } +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); }; +Object.defineProperty(exports, "__esModule", { value: true }); +const _ = require("lodash"); +const meta = require("../meta"); +const db = require("../database"); +const plugins = require("../plugins"); +const user = require("../user"); +const topics = require("../topics"); +const categories = require("../categories"); +const groups = require("../groups"); +const privileges = require("../privileges"); +function createPosts(Posts) { + function checkToPid(toPid, uid) { + return __awaiter(this, void 0, void 0, function* () { + const [toPost, canViewToPid] = yield Promise.all([ + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + Posts.getPostFields(toPid, ['pid', 'deleted']), + privileges.posts.can('posts:view_deleted', toPid, uid), + ]); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + const toPidExists = !!toPost.pid; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (!toPidExists || (toPost.deleted && !canViewToPid)) { + throw new Error('[[error:invalid-pid]]'); + } + }); + } + function addReplyTo(postData, timestamp) { + return __awaiter(this, void 0, void 0, function* () { + if (!postData.toPid) { + return; + } + yield Promise.all([ + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.sortedSetAdd(`pid:${postData.toPid}:replies`, timestamp, postData.pid), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.incrObjectField(`post:${postData.toPid}`, 'replies'), + ]); + }); + } + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + Posts.create = function (data) { + return __awaiter(this, void 0, void 0, function* () { + // This is an internal method, consider using Topics.reply instead + const { uid, tid, content, timestamp = Date.now(), isMain = false } = data; + if (!uid && parseInt(uid.toString(), 10) !== 0) { + throw new Error('[[error:invalid-uid]]'); + } + if (data.toPid) { + yield checkToPid(data.toPid, uid); + } + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + const pid = yield db.incrObjectField('global', 'nextPid'); + let postData = { + pid: pid, + uid: uid, + tid: tid, + content: content.toString(), + timestamp: timestamp, + }; + if (data.toPid) { + postData.toPid = data.toPid; + } + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (data.ip && meta.config.trackIpPerPost) { + postData.ip = data.ip; + } + if (data.handle && !parseInt(uid.toString(), 10)) { + postData.handle = data.handle; + } + let result = yield plugins.hooks.fire('filter:post.create', { post: postData, data: data }); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + postData = result.post; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + yield db.setObject(`post:${postData.pid}`, postData); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const topicData = yield topics.getTopicFields(tid, ['cid', 'pinned']); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + postData.cid = topicData.cid; + yield Promise.all([ + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.sortedSetAdd('posts:pid', timestamp, postData.pid), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.incrObjectField('global', 'postCount'), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + user.onNewPostMade(postData), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + topics.onNewPostMade(postData), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + categories.onNewPostMade(topicData.cid, topicData.pinned, postData), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + groups.onNewPostMade(postData), + addReplyTo(postData, timestamp), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + Posts.uploads.sync(postData.pid), + ]); + result = (yield plugins.hooks.fire('filter:post.get', { post: postData, uid: data.uid })); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + result.post.isMain = isMain; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + yield plugins.hooks.fire('action:post.save', { post: _.clone(result.post) }); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return result.post; + }); + }; +} +module.exports = createPosts; diff --git a/src/posts/create.ts b/src/posts/create.ts new file mode 100644 index 0000000000..f38b2faec6 --- /dev/null +++ b/src/posts/create.ts @@ -0,0 +1,164 @@ +import _ = require('lodash'); +import meta = require('../meta'); +import db = require('../database'); +import plugins = require('../plugins'); +import user = require('../user'); +import topics = require('../topics'); +import categories = require('../categories'); +import groups = require('../groups'); +import privileges = require('../privileges'); + +/** + * Data required to create a post. + */ +interface PostData { + uid: number; // User ID of the post author + tid: number; // Topic ID where the post will be created + content: string; // Content of the post + timestamp?: number; // Timestamp of when the post was created (optional) + isMain?: boolean; // Indicates if the post is the main post in the topic (optional) + toPid?: number; // Parent post ID if this post is a reply (optional) + ip?: string; // IP address of the post author (optional) + handle?: string; // Handle or username of the post author (optional) +} + +/** + * Represents a post. + */ +interface Post { + pid: number; // Post ID + uid: number; // User ID of the post author + tid: number; // Topic ID where the post is located + content: string; // Content of the post + timestamp: number; // Timestamp of when the post was created + toPid?: number; // Parent post ID if this post is a reply (optional) + ip?: string; // IP address of the post author (optional) + handle?: string; // Handle or username of the post author (optional) + cid?: number; // Category ID where the post is located (optional) + isMain?: boolean; // Indicates if the post is the main post in the topic (optional) + deleted?: boolean; // Indicates if the post is deleted (optional) + getPostFields?(pid: number, fields: string[]): Promise; // Retrieves specific fields of a post (optional) + create?(data: PostData): Promise; // Creates a new post (optional) + uploads?: { + sync(pid: number): void; // Synchronizes uploads for a specific post (optional) + }; +} +function createPosts(Posts: Post) { + async function checkToPid(toPid: number, uid: number): Promise { + const [toPost, canViewToPid] = await Promise.all([ + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + Posts.getPostFields(toPid, ['pid', 'deleted']), + privileges.posts.can('posts:view_deleted', toPid, uid), + ]) as [Post, boolean]; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + const toPidExists = !!toPost.pid; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (!toPidExists || (toPost.deleted && !canViewToPid)) { + throw new Error('[[error:invalid-pid]]'); + } + } + async function addReplyTo(postData: Post, timestamp: number): Promise { + if (!postData.toPid) { + return; + } + await Promise.all([ + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.sortedSetAdd(`pid:${postData.toPid}:replies`, timestamp, postData.pid), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.incrObjectField(`post:${postData.toPid}`, 'replies'), + ]); + } + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + Posts.create = async function (data: PostData): Promise { + // This is an internal method, consider using Topics.reply instead + const { uid, tid, content, timestamp = Date.now(), isMain = false } = data; + if (!uid && parseInt(uid.toString(), 10) !== 0) { + throw new Error('[[error:invalid-uid]]'); + } + + if (data.toPid) { + await checkToPid(data.toPid, uid); + } + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + const pid: number = await db.incrObjectField('global', 'nextPid') as number; + let postData: Post = { + pid: pid, + uid: uid, + tid: tid, + content: content.toString(), + timestamp: timestamp, + }; + + if (data.toPid) { + postData.toPid = data.toPid; + } + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (data.ip && meta.config.trackIpPerPost) { + postData.ip = data.ip; + } + if (data.handle && !parseInt(uid.toString(), 10)) { + postData.handle = data.handle; + } + + let result: { post: Post } = await plugins.hooks.fire('filter:post.create', { post: postData, data: data }) as { post: Post }; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + postData = result.post; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + await db.setObject(`post:${postData.pid}`, postData); + + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const topicData = await topics.getTopicFields(tid, ['cid', 'pinned']) as { cid: number; pinned: boolean }; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + postData.cid = topicData.cid; + + await Promise.all([ + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.sortedSetAdd('posts:pid', timestamp, postData.pid), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + db.incrObjectField('global', 'postCount'), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + user.onNewPostMade(postData), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + topics.onNewPostMade(postData), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + categories.onNewPostMade(topicData.cid, topicData.pinned, postData), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + groups.onNewPostMade(postData), + addReplyTo(postData, timestamp), + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + Posts.uploads.sync(postData.pid), + ]); + + result = await plugins.hooks.fire('filter:post.get', { post: postData, uid: data.uid }) as { post: Post }; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + result.post.isMain = isMain; + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + await plugins.hooks.fire('action:post.save', { post: _.clone(result.post) }); + // La siguiente línea llama a una función en un módulo que aún no ha sido actualizado a TS + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + return result.post; + }; +} + +module.exports = createPosts;