Files
outline/server/models/FileOperation.ts
Apoorv Mishra 7e61a519f1 Type server models (#6326)
* fix: type server models

* fix: make ParanoidModel generic

* fix: ApiKey

* fix: Attachment

* fix: AuthenticationProvider

* fix: Backlink

* fix: Collection

* fix: Comment

* fix: Document

* fix: FileOperation

* fix: Group

* fix: GroupPermission

* fix: GroupUser

* fix: Integration

* fix: IntegrationAuthentication

* fix: Notification

* fix: Pin

* fix: Revision

* fix: SearchQuery

* fix: Share

* fix: Star

* fix: Subscription

* fix: TypeError

* fix: Imports

* fix: Team

* fix: TeamDomain

* fix: User

* fix: UserAuthentication

* fix: UserPermission

* fix: View

* fix: WebhookDelivery

* fix: WebhookSubscription

* Remove type duplication

---------

Co-authored-by: Tom Moor <tom.moor@gmail.com>
2024-01-12 22:33:05 +05:30

157 lines
3.1 KiB
TypeScript

import {
InferAttributes,
InferCreationAttributes,
Op,
WhereOptions,
} from "sequelize";
import {
ForeignKey,
DefaultScope,
Column,
BeforeDestroy,
BelongsTo,
Table,
DataType,
} from "sequelize-typescript";
import {
FileOperationFormat,
FileOperationState,
FileOperationType,
} from "@shared/types";
import FileStorage from "@server/storage/files";
import Collection from "./Collection";
import Team from "./Team";
import User from "./User";
import ParanoidModel from "./base/ParanoidModel";
import Fix from "./decorators/Fix";
@DefaultScope(() => ({
include: [
{
model: User,
as: "user",
paranoid: false,
},
{
model: Collection,
as: "collection",
paranoid: false,
},
],
}))
@Table({ tableName: "file_operations", modelName: "file_operation" })
@Fix
class FileOperation extends ParanoidModel<
InferAttributes<FileOperation>,
Partial<InferCreationAttributes<FileOperation>>
> {
@Column(DataType.ENUM(...Object.values(FileOperationType)))
type: FileOperationType;
@Column(DataType.STRING)
format: FileOperationFormat;
@Column(DataType.ENUM(...Object.values(FileOperationState)))
state: FileOperationState;
@Column
key: string;
@Column
url?: string | null;
@Column
error: string | null;
@Column(DataType.BIGINT)
size: number;
@Column(DataType.BOOLEAN)
includeAttachments: boolean;
/**
* Mark the current file operation as expired and remove the file from storage.
*/
expire = async function () {
this.state = FileOperationState.Expired;
try {
await FileStorage.deleteFile(this.key);
} catch (err) {
if (err.retryable) {
throw err;
}
}
return this.save();
};
/**
* The file operation contents as a readable stream.
*/
get stream() {
return FileStorage.getFileStream(this.key);
}
/**
* The file operation contents as a handle which contains a path and cleanup function.
*/
get handle() {
return FileStorage.getFileHandle(this.key);
}
// hooks
@BeforeDestroy
static async deleteFileFromS3(model: FileOperation) {
await FileStorage.deleteFile(model.key);
}
// associations
@BelongsTo(() => User, "userId")
user: User;
@ForeignKey(() => User)
@Column(DataType.UUID)
userId: string;
@BelongsTo(() => Team, "teamId")
team: Team;
@ForeignKey(() => Team)
@Column(DataType.UUID)
teamId: string;
@BelongsTo(() => Collection, "collectionId")
collection: Collection;
@ForeignKey(() => Collection)
@Column(DataType.UUID)
collectionId?: string | null;
/**
* Count the number of export file operations for a given team after a point
* in time.
*
* @param teamId The team id
* @param startDate The start time
* @returns The number of file operations
*/
static async countExportsAfterDateTime(
teamId: string,
startDate: Date,
where: WhereOptions<FileOperation> = {}
): Promise<number> {
return this.count({
where: {
teamId,
createdAt: {
[Op.gt]: startDate,
},
...where,
},
});
}
}
export default FileOperation;