@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
185 lines (184 loc) • 14.1 kB
JavaScript
/*
* Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
* This file is part of Sync-in | The open source file sync and share solution
* See the LICENSE file for licensing details
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "CommentsQueries", {
enumerable: true,
get: function() {
return CommentsQueries;
}
});
const _common = require("@nestjs/common");
const _drizzleorm = require("drizzle-orm");
const _mysqlcore = require("drizzle-orm/mysql-core");
const _constants = require("../../../infrastructure/database/constants");
const _utils = require("../../../infrastructure/database/utils");
const _filesschema = require("../../files/schemas/files.schema");
const _sharesschema = require("../../shares/schemas/shares.schema");
const _sharesqueriesservice = require("../../shares/services/shares-queries.service");
const _spaces = require("../../spaces/constants/spaces");
const _spacesrootsschema = require("../../spaces/schemas/spaces-roots.schema");
const _spacesschema = require("../../spaces/schemas/spaces.schema");
const _spacesqueriesservice = require("../../spaces/services/spaces-queries.service");
const _usersschema = require("../../users/schemas/users.schema");
const _commentsschema = require("../schemas/comments.schema");
function _ts_decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
function _ts_param(paramIndex, decorator) {
return function(target, key) {
decorator(target, key, paramIndex);
};
}
let CommentsQueries = class CommentsQueries {
getComments(userId, isFileOwner, fromFileId, fromCommentId, limit = undefined) {
let where;
if (fromFileId) {
where = (0, _drizzleorm.eq)(_commentsschema.comments.fileId, fromFileId);
} else if (fromCommentId) {
where = (0, _drizzleorm.eq)(_commentsschema.comments.id, fromCommentId);
limit = 1;
} else {
throw Error('fromFileId or fromCommentId must be provided');
}
return this.db.select({
...(0, _drizzleorm.getTableColumns)(_commentsschema.comments),
author: {
login: _usersschema.users.login,
fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users),
email: _usersschema.users.email,
isAuthor: (0, _drizzleorm.sql)`${_usersschema.users.id} = ${userId}`.mapWith(Boolean)
},
isFileOwner: (0, _drizzleorm.sql)`${+isFileOwner}`.mapWith(Boolean)
}).from(_commentsschema.comments).leftJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, _commentsschema.comments.userId)).where(where).orderBy((0, _drizzleorm.desc)(_commentsschema.comments.id)).limit(limit);
}
async createComment(userId, fileId, content) {
return (0, _utils.dbGetInsertedId)(await this.db.insert(_commentsschema.comments).values({
userId: userId,
fileId: fileId,
content: content
}));
}
async updateComment(userId, commentId, fileId, content) {
return (0, _utils.dbCheckAffectedRows)(await this.db.update(_commentsschema.comments).set({
content: content
}).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_commentsschema.comments.userId, userId), (0, _drizzleorm.eq)(_commentsschema.comments.id, commentId), (0, _drizzleorm.eq)(_commentsschema.comments.fileId, fileId))).limit(1), 1, false);
}
async deleteComment(userId, commentId, fileId, isFileOwner) {
return (0, _utils.dbCheckAffectedRows)(await this.db.delete(_commentsschema.comments).where((0, _drizzleorm.and)((0, _drizzleorm.or)((0, _drizzleorm.eq)((0, _drizzleorm.sql)`${+isFileOwner}`, 1), (0, _drizzleorm.eq)(_commentsschema.comments.userId, userId)), (0, _drizzleorm.eq)(_commentsschema.comments.id, commentId), (0, _drizzleorm.eq)(_commentsschema.comments.fileId, fileId))).limit(1), 1, false);
}
membersToNotify(fromUserId, fileId) {
/* lists the owner of the file and the users who have commented on it */ const select = {
id: _usersschema.users.id,
email: _usersschema.users.email,
language: _usersschema.users.language,
notification: _usersschema.users.notification
};
const fromComments = this.db.select(select).from(_commentsschema.comments).innerJoin(_usersschema.users, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersschema.users.id, _commentsschema.comments.userId), (0, _drizzleorm.ne)(_usersschema.users.id, fromUserId))).where((0, _drizzleorm.eq)(_commentsschema.comments.fileId, fileId));
const fromFile = this.db.select(select).from(_filesschema.files).innerJoin(_usersschema.users, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersschema.users.id, _filesschema.files.ownerId), (0, _drizzleorm.ne)(_usersschema.users.id, fromUserId))).where((0, _drizzleorm.eq)(_filesschema.files.id, fileId));
return (0, _mysqlcore.union)(fromComments, fromFile);
}
getRecentsFromShares(userId, shareIds, limit) {
const shareFile = (0, _mysqlcore.alias)(_filesschema.files, 'shareFile');
return this.db.select({
id: _commentsschema.comments.id,
content: _commentsschema.comments.content,
modifiedAt: _commentsschema.comments.modifiedAt,
author: {
login: _usersschema.users.login,
fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users).as('fullName'),
email: _usersschema.users.email
},
file: {
name: (0, _drizzleorm.sql)`IF (${_filesschema.files.id} = ${shareFile.id}, ${_sharesschema.shares.name}, ${_filesschema.files.name})`.as('name'),
path: (0, _drizzleorm.sql)`
CONCAT_WS('/', '${_drizzleorm.sql.raw(_spaces.SPACE_REPOSITORY.SHARES)}',
IF (${shareFile.id} IS NOT NULL,
IF (${_filesschema.files.id} = ${shareFile.id}, NULL, REGEXP_REPLACE(${_filesschema.files.path}, ${(0, _filesschema.filePathSQL)(shareFile)}, ${_sharesschema.shares.alias})),
CONCAT_WS('/', ${_sharesschema.shares.alias}, IF (${_filesschema.files.path} = '.', NULL, ${_filesschema.files.path}))
)
)`.as('path'),
mime: _filesschema.files.mime,
inTrash: (0, _drizzleorm.sql)`0`.as('inTrash'),
fromSpace: (0, _drizzleorm.sql)`0`.as('fromSpace'),
fromShare: (0, _drizzleorm.sql)`1`.as('fromShare')
}
}).from(_sharesschema.shares).leftJoin(shareFile, (0, _drizzleorm.eq)(shareFile.id, _sharesschema.shares.fileId)).leftJoin(_spacesschema.spaces, (0, _drizzleorm.eq)(_spacesschema.spaces.id, shareFile.spaceId)).leftJoin(_spacesrootsschema.spacesRoots, (0, _drizzleorm.eq)(_spacesrootsschema.spacesRoots.spaceId, _spacesschema.spaces.id)).leftJoin(_filesschema.files, (0, _drizzleorm.or)(// file linked to the share
(0, _drizzleorm.eq)(_filesschema.files.id, shareFile.id), // all files with an external share id
(0, _drizzleorm.and)((0, _drizzleorm.isNull)(shareFile.id), (0, _drizzleorm.eq)(_filesschema.files.shareExternalId, _sharesschema.shares.id)), // all files under the share
(0, _drizzleorm.and)((0, _drizzleorm.isNotNull)(shareFile.id), (0, _drizzleorm.eq)(shareFile.isDir, true), (0, _drizzleorm.sql)`${_filesschema.files.spaceId} <=> ${shareFile.spaceId}`, (0, _drizzleorm.sql)`${_filesschema.files.ownerId} <=> ${shareFile.ownerId}`, (0, _drizzleorm.sql)`${_filesschema.files.spaceExternalRootId} <=> ${shareFile.spaceExternalRootId}`, (0, _drizzleorm.sql)`${_filesschema.files.shareExternalId} <=> ${shareFile.shareExternalId}`, (0, _drizzleorm.sql)`${_filesschema.files.path} REGEXP CONCAT('^', IF(${shareFile.path} = '.', CONCAT(${shareFile.name}, '(/.*|)$'), CONCAT(${shareFile.path}, '/')))`))).innerJoin(_commentsschema.comments, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_commentsschema.comments.fileId, _filesschema.files.id), (0, _drizzleorm.ne)(_commentsschema.comments.userId, userId))).innerJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, _commentsschema.comments.userId)).where((0, _drizzleorm.inArray)(_sharesschema.shares.id, shareIds)).groupBy(_commentsschema.comments.id).orderBy((0, _drizzleorm.desc)(_commentsschema.comments.id)).limit(limit);
}
getRecentsFromSpaces(userId, spaceIds, limit) {
const spaceRootFile = (0, _mysqlcore.alias)(_filesschema.files, 'spaceRootFile');
return this.db.select({
id: _commentsschema.comments.id,
content: _commentsschema.comments.content,
modifiedAt: _commentsschema.comments.modifiedAt,
author: {
login: _usersschema.users.login,
fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users).as('fullName'),
email: _usersschema.users.email
},
file: {
name: (0, _drizzleorm.sql)`IF (${_filesschema.files.id} = ${_spacesrootsschema.spacesRoots.fileId}, ${_spacesrootsschema.spacesRoots.name}, ${_filesschema.files.name})`.as('name'),
path: (0, _drizzleorm.sql)`
CONCAT_WS('/', IF (${_filesschema.files.inTrash} = 0, '${_drizzleorm.sql.raw(_spaces.SPACE_REPOSITORY.FILES)}', '${_drizzleorm.sql.raw(_spaces.SPACE_REPOSITORY.TRASH)}'),
IF (${_filesschema.files.ownerId} = ${userId}, '${_drizzleorm.sql.raw(_spaces.SPACE_ALIAS.PERSONAL)}', ${_spacesschema.spaces.alias}),
IF (${spaceRootFile.id} IS NOT NULL,
IF (${_filesschema.files.id} = ${spaceRootFile.id}, NULL, REGEXP_REPLACE(${_filesschema.files.path}, ${(0, _filesschema.filePathSQL)(spaceRootFile)}, ${_spacesrootsschema.spacesRoots.alias})),
NULLIF(
CONCAT_WS('/',
IF (${_filesschema.files.spaceExternalRootId} = ${_spacesrootsschema.spacesRoots.id}, ${_spacesrootsschema.spacesRoots.alias}, NULL),
IF (${_filesschema.files.path} = '.', NULL, ${_filesschema.files.path})
)
, '')
)
)`.as('path'),
mime: _filesschema.files.mime,
inTrash: (0, _drizzleorm.sql)`${_filesschema.files.inTrash}`.as('inTrash'),
fromSpace: (0, _drizzleorm.sql)`IF (${_filesschema.files.ownerId} = ${userId}, 0, 1)`.as('fromSpace'),
fromShare: (0, _drizzleorm.sql)`0`.as('fromShare')
}
}).from(_spacesschema.spaces).leftJoin(_spacesrootsschema.spacesRoots, (0, _drizzleorm.eq)(_spacesrootsschema.spacesRoots.spaceId, _spacesschema.spaces.id)).leftJoin(spaceRootFile, (0, _drizzleorm.eq)(spaceRootFile.id, _spacesrootsschema.spacesRoots.fileId)).leftJoin(_filesschema.files, (0, _drizzleorm.or)(// all files from user
(0, _drizzleorm.eq)(_filesschema.files.ownerId, userId), // all files from spaces
(0, _drizzleorm.eq)(_filesschema.files.spaceId, _spacesschema.spaces.id), // all files from space roots
(0, _drizzleorm.eq)(_filesschema.files.id, _spacesrootsschema.spacesRoots.fileId), // all files under the space roots
(0, _drizzleorm.and)((0, _drizzleorm.isNotNull)(spaceRootFile.id), (0, _drizzleorm.eq)(spaceRootFile.isDir, true), (0, _drizzleorm.sql)`${_filesschema.files.ownerId} <=> ${spaceRootFile.ownerId}`, (0, _drizzleorm.sql)`${_filesschema.files.path} REGEXP CONCAT('^', IF(${spaceRootFile.path} = '.', CONCAT(${spaceRootFile.name}, '(/.*|)$'), CONCAT(${spaceRootFile.path}, '/')))`))).innerJoin(_commentsschema.comments, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_commentsschema.comments.fileId, _filesschema.files.id), (0, _drizzleorm.ne)(_commentsschema.comments.userId, userId))).innerJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, _commentsschema.comments.userId)).where((0, _drizzleorm.inArray)(_spacesschema.spaces.id, spaceIds)).groupBy(_commentsschema.comments.id).orderBy((0, _drizzleorm.desc)(_commentsschema.comments.id)).limit(limit);
}
async getRecentsFromUser(user, limit = 10) {
const [spaceIds, shareIds] = await Promise.all([
this.spacesQueries.spaceIds(user.id),
this.sharesQueries.shareIds(user.id, +user.isAdmin)
]);
const fromSpaces = this.getRecentsFromSpaces(user.id, spaceIds, limit * 2);
const fromShares = this.getRecentsFromShares(user.id, shareIds, limit * 2);
const unionAlias = (0, _mysqlcore.union)(fromSpaces, fromShares).as('unionAlias');
return this.db.select().from(unionAlias).groupBy(unionAlias.id).orderBy((0, _drizzleorm.desc)(unionAlias.id)).limit(limit);
}
constructor(db, spacesQueries, sharesQueries){
this.db = db;
this.spacesQueries = spacesQueries;
this.sharesQueries = sharesQueries;
}
};
CommentsQueries = _ts_decorate([
(0, _common.Injectable)(),
_ts_param(0, (0, _common.Inject)(_constants.DB_TOKEN_PROVIDER)),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof DBSchema === "undefined" ? Object : DBSchema,
typeof _spacesqueriesservice.SpacesQueries === "undefined" ? Object : _spacesqueriesservice.SpacesQueries,
typeof _sharesqueriesservice.SharesQueries === "undefined" ? Object : _sharesqueriesservice.SharesQueries
])
], CommentsQueries);
//# sourceMappingURL=comments-queries.service.js.map