Files
outline/server/types.ts
Tom Moor f675a04735 chore: Rename GroupPermission -> GroupMembership (#7214)
* GroupPermission -> GroupMembership

* Add group membership source

* wip
2024-07-17 16:31:20 -07:00

536 lines
12 KiB
TypeScript

import { ParameterizedContext, DefaultContext } from "koa";
import { IRouterParamContext } from "koa-router";
import { InferAttributes, Model, Transaction } from "sequelize";
import { z } from "zod";
import {
CollectionSort,
NavigationNode,
Client,
CollectionPermission,
DocumentPermission,
JSONValue,
UnfurlResourceType,
ProsemirrorData,
} from "@shared/types";
import { BaseSchema } from "@server/routes/api/schema";
import { AccountProvisionerResult } from "./commands/accountProvisioner";
import type {
ApiKey,
Attachment,
AuthenticationProvider,
FileOperation,
Revision,
Team,
User,
UserMembership,
WebhookSubscription,
Pin,
Star,
Document,
Collection,
Group,
Integration,
Comment,
Subscription,
View,
Notification,
Share,
GroupMembership,
} from "./models";
export enum AuthenticationType {
API = "api",
APP = "app",
}
export type AuthenticationResult = AccountProvisionerResult & {
client: Client;
};
export type Authentication = {
user: User;
token: string;
type: AuthenticationType;
};
export type Pagination = {
limit: number;
offset: number;
nextPath: string;
};
export type AppState = {
auth: Authentication | Record<string, never>;
transaction: Transaction;
pagination: Pagination;
};
export type AppContext = ParameterizedContext<AppState, DefaultContext>;
export type BaseReq = z.infer<typeof BaseSchema>;
export type BaseRes = unknown;
export interface APIContext<ReqT = BaseReq, ResT = BaseRes>
extends ParameterizedContext<
AppState,
DefaultContext & IRouterParamContext<AppState>,
ResT
> {
/** Typed and validated version of request, consisting of validated body, query, etc */
input: ReqT;
}
type BaseEvent<T extends Model> = {
teamId: string;
actorId: string;
ip: string;
changes?: {
attributes: Partial<InferAttributes<T>>;
previous: Partial<InferAttributes<T>>;
};
};
export type ApiKeyEvent = BaseEvent<ApiKey> & {
name: "api_keys.create" | "api_keys.delete";
modelId: string;
data: {
name: string;
};
};
export type AttachmentEvent = BaseEvent<Attachment> &
(
| {
name: "attachments.create";
modelId: string;
data: {
name: string;
source?: "import";
};
}
| {
name: "attachments.delete";
modelId: string;
data: {
name: string;
};
}
);
export type AuthenticationProviderEvent = BaseEvent<AuthenticationProvider> & {
name: "authenticationProviders.update";
modelId: string;
data: {
enabled: boolean;
};
};
export type UserEvent = BaseEvent<User> &
(
| {
name:
| "users.signin"
| "users.signout"
| "users.update"
| "users.suspend"
| "users.activate"
| "users.delete";
userId: string;
}
| {
name: "users.create" | "users.promote" | "users.demote";
userId: string;
data: {
name: string;
};
}
| {
name: "users.invite";
userId: string;
data: {
email: string;
name: string;
};
}
);
export type UserMembershipEvent = BaseEvent<UserMembership> & {
name: "userMemberships.update";
modelId: string;
userId: string;
documentId: string;
data: {
index: string | null;
};
};
export type DocumentEvent = BaseEvent<Document> &
(
| {
name:
| "documents.create"
| "documents.publish"
| "documents.unpublish"
| "documents.delete"
| "documents.permanent_delete"
| "documents.archive"
| "documents.unarchive"
| "documents.restore";
documentId: string;
collectionId: string;
data: {
title: string;
source?: "import";
};
}
| {
name: "documents.move";
documentId: string;
collectionId: string;
data: {
collectionIds: string[];
documentIds: string[];
};
}
| {
name:
| "documents.update"
| "documents.update.delayed"
| "documents.update.debounced";
documentId: string;
collectionId: string;
createdAt: string;
data: {
title: string;
autosave: boolean;
done: boolean;
};
}
| {
name: "documents.title_change";
documentId: string;
collectionId: string;
createdAt: string;
data: {
title: string;
previousTitle: string;
};
}
);
export type RevisionEvent = BaseEvent<Revision> & {
name: "revisions.create";
documentId: string;
collectionId: string;
modelId: string;
};
export type FileOperationEvent = BaseEvent<FileOperation> & {
name:
| "fileOperations.create"
| "fileOperations.update"
| "fileOperations.delete";
modelId: string;
data: Partial<FileOperation>;
};
export type CollectionUserEvent = BaseEvent<UserMembership> & {
name: "collections.add_user" | "collections.remove_user";
userId: string;
modelId: string;
collectionId: string;
data: {
isNew?: boolean;
permission?: CollectionPermission;
};
};
export type CollectionGroupEvent = BaseEvent<GroupMembership> & {
name: "collections.add_group" | "collections.remove_group";
collectionId: string;
modelId: string;
data: { name: string };
};
export type DocumentUserEvent = BaseEvent<UserMembership> & {
name: "documents.add_user" | "documents.remove_user";
userId: string;
modelId: string;
documentId: string;
data: {
title: string;
isNew?: boolean;
permission?: DocumentPermission;
};
};
export type DocumentGroupEvent = BaseEvent<GroupMembership> & {
name: "documents.add_group" | "documents.remove_group";
documentId: string;
modelId: string;
data: { name: string };
};
export type CollectionEvent = BaseEvent<Collection> &
(
| {
name: "collections.create";
collectionId: string;
data: {
name: string;
source?: "import";
};
}
| {
name: "collections.update" | "collections.delete";
collectionId: string;
data: {
name: string;
};
}
| {
name: "collections.move";
collectionId: string;
data: {
index: string;
};
}
| {
name: "collections.permission_changed";
collectionId: string;
data: {
privacyChanged: boolean;
sharingChanged: boolean;
};
}
);
export type GroupUserEvent = BaseEvent<UserMembership> & {
name: "groups.add_user" | "groups.remove_user";
userId: string;
modelId: string;
data: {
name: string;
};
};
export type GroupEvent = BaseEvent<Group> &
(
| GroupUserEvent
| {
name: "groups.create" | "groups.delete" | "groups.update";
modelId: string;
data: {
name: string;
};
}
);
export type IntegrationEvent = BaseEvent<Integration> & {
name: "integrations.create" | "integrations.update" | "integrations.delete";
modelId: string;
};
export type TeamEvent = BaseEvent<Team> & {
name: "teams.create" | "teams.update" | "teams.delete" | "teams.destroy";
};
export type PinEvent = BaseEvent<Pin> & {
name: "pins.create" | "pins.update" | "pins.delete";
modelId: string;
documentId: string;
collectionId?: string;
};
export type CommentUpdateEvent = BaseEvent<Comment> & {
name: "comments.update";
modelId: string;
documentId: string;
actorId: string;
data?: {
newMentionIds: string[];
};
};
export type CommentEvent =
| (BaseEvent<Comment> & {
name: "comments.create";
modelId: string;
documentId: string;
actorId: string;
})
| CommentUpdateEvent
| (BaseEvent<Comment> & {
name: "comments.delete";
modelId: string;
documentId: string;
actorId: string;
collectionId: string;
});
export type StarEvent = BaseEvent<Star> & {
name: "stars.create" | "stars.update" | "stars.delete";
modelId: string;
documentId: string;
userId: string;
};
export type ShareEvent = BaseEvent<Share> & {
name: "shares.create" | "shares.update" | "shares.revoke";
modelId: string;
documentId: string;
collectionId?: string;
data: {
name: string;
};
};
export type SubscriptionEvent = BaseEvent<Subscription> & {
name: "subscriptions.create" | "subscriptions.delete";
modelId: string;
userId: string;
documentId: string | null;
};
export type ViewEvent = BaseEvent<View> & {
name: "views.create";
documentId: string;
collectionId: string;
modelId: string;
data: {
title: string;
};
};
export type WebhookDeliveryStatus = "pending" | "success" | "failed";
export type WebhookSubscriptionEvent = BaseEvent<WebhookSubscription> & {
name:
| "webhookSubscriptions.create"
| "webhookSubscriptions.delete"
| "webhookSubscriptions.update";
modelId: string;
data: {
name: string;
url: string;
events: string[];
};
};
export type NotificationEvent = BaseEvent<Notification> & {
name: "notifications.create" | "notifications.update";
modelId: string;
teamId: string;
userId: string;
actorId: string;
commentId?: string;
documentId?: string;
collectionId?: string;
};
export type Event =
| ApiKeyEvent
| AttachmentEvent
| AuthenticationProviderEvent
| DocumentEvent
| DocumentUserEvent
| DocumentGroupEvent
| PinEvent
| CommentEvent
| StarEvent
| CollectionEvent
| CollectionUserEvent
| CollectionGroupEvent
| FileOperationEvent
| IntegrationEvent
| GroupEvent
| RevisionEvent
| ShareEvent
| SubscriptionEvent
| TeamEvent
| UserEvent
| UserMembershipEvent
| ViewEvent
| WebhookSubscriptionEvent
| NotificationEvent;
export type NotificationMetadata = {
notificationId?: string;
};
export type JSONExportMetadata = {
/** The version of the export, allows updated structure in the future. */
exportVersion: number;
/** The version of the application that created the export. */
version: string;
/** The date the export was created. */
createdAt: string;
/** The ID of the user that created the export. */
createdById: string;
/** The email of the user that created the export. */
createdByEmail: string | null;
};
export type DocumentJSONExport = {
id: string;
urlId: string;
title: string;
/**
* For backward compatibility, maintain the `emoji` field.
* Future exports will use the `icon` field.
* */
emoji?: string | null;
icon: string | null;
color: string | null;
data: Record<string, any>;
createdById: string;
createdByName: string;
createdByEmail: string | null;
createdAt: string;
updatedAt: string;
publishedAt: string | null;
fullWidth: boolean;
template: boolean;
parentDocumentId: string | null;
};
export type AttachmentJSONExport = {
id: string;
documentId: string | null;
contentType: string;
name: string;
size: number;
key: string;
};
export type CollectionJSONExport = {
collection: {
id: string;
urlId: string;
name: string;
data?: ProsemirrorData | null;
description?: ProsemirrorData | null;
permission?: CollectionPermission | null;
color?: string | null;
icon?: string | null;
sort: CollectionSort;
documentStructure: NavigationNode[] | null;
};
documents: {
[id: string]: DocumentJSONExport;
};
attachments: {
[id: string]: AttachmentJSONExport;
};
};
export type Unfurl = { [x: string]: JSONValue; type: UnfurlResourceType };
export type UnfurlSignature = (
url: string,
actor?: User
) => Promise<Unfurl | void>;
export type UninstallSignature = (integration: Integration) => Promise<void>;