fluxer/packages/elasticsearch_search/src/ElasticsearchIndexDefinitions.tsx
2026-02-21 16:41:56 +00:00

206 lines
5.1 KiB
TypeScript

/*
* Copyright (C) 2026 Fluxer Contributors
*
* This file is part of Fluxer.
*
* Fluxer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Fluxer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
*/
type ElasticsearchFieldType = 'text' | 'keyword' | 'boolean' | 'long' | 'integer' | 'date' | 'float';
export type FluxerSearchIndexName = 'messages' | 'guilds' | 'users' | 'reports' | 'audit_logs' | 'guild_members';
export interface ElasticsearchFieldMapping {
type: ElasticsearchFieldType;
index?: boolean;
fields?: Record<string, ElasticsearchFieldMapping>;
}
export interface ElasticsearchIndexSettings {
number_of_shards?: number;
number_of_replicas?: number;
}
export interface ElasticsearchIndexDefinition {
indexName: FluxerSearchIndexName;
mappings: {
properties: Record<string, ElasticsearchFieldMapping>;
};
settings?: ElasticsearchIndexSettings;
}
function textWithKeyword(): ElasticsearchFieldMapping {
return {type: 'text', fields: {keyword: {type: 'keyword'}}};
}
function keyword(): ElasticsearchFieldMapping {
return {type: 'keyword'};
}
function bool(): ElasticsearchFieldMapping {
return {type: 'boolean'};
}
function long(): ElasticsearchFieldMapping {
return {type: 'long'};
}
function integer(): ElasticsearchFieldMapping {
return {type: 'integer'};
}
export const ELASTICSEARCH_INDEX_DEFINITIONS: Record<FluxerSearchIndexName, ElasticsearchIndexDefinition> = {
messages: {
indexName: 'messages',
mappings: {
properties: {
id: keyword(),
channelId: keyword(),
guildId: keyword(),
authorId: keyword(),
authorType: keyword(),
content: textWithKeyword(),
createdAt: long(),
editedAt: long(),
isPinned: bool(),
mentionedUserIds: keyword(),
mentionEveryone: bool(),
hasLink: bool(),
hasEmbed: bool(),
hasPoll: bool(),
hasFile: bool(),
hasVideo: bool(),
hasImage: bool(),
hasSound: bool(),
hasSticker: bool(),
hasForward: bool(),
embedTypes: keyword(),
embedProviders: keyword(),
linkHostnames: keyword(),
attachmentFilenames: keyword(),
attachmentExtensions: keyword(),
},
},
},
guilds: {
indexName: 'guilds',
mappings: {
properties: {
id: keyword(),
ownerId: keyword(),
name: textWithKeyword(),
vanityUrlCode: textWithKeyword(),
discoveryDescription: textWithKeyword(),
iconHash: keyword(),
bannerHash: keyword(),
splashHash: keyword(),
features: keyword(),
verificationLevel: integer(),
mfaLevel: integer(),
nsfwLevel: integer(),
createdAt: long(),
discoveryCategory: integer(),
isDiscoverable: bool(),
},
},
},
users: {
indexName: 'users',
mappings: {
properties: {
id: textWithKeyword(),
username: textWithKeyword(),
email: textWithKeyword(),
phone: textWithKeyword(),
discriminator: integer(),
isBot: bool(),
isSystem: bool(),
flags: keyword(),
premiumType: integer(),
emailVerified: bool(),
emailBounced: bool(),
suspiciousActivityFlags: integer(),
acls: keyword(),
createdAt: long(),
lastActiveAt: long(),
tempBannedUntil: long(),
pendingDeletionAt: long(),
stripeSubscriptionId: keyword(),
stripeCustomerId: keyword(),
},
},
},
reports: {
indexName: 'reports',
mappings: {
properties: {
id: keyword(),
reporterId: keyword(),
reportedAt: long(),
status: integer(),
reportType: integer(),
category: textWithKeyword(),
additionalInfo: textWithKeyword(),
reportedUserId: keyword(),
reportedGuildId: keyword(),
reportedGuildName: textWithKeyword(),
reportedMessageId: keyword(),
reportedChannelId: keyword(),
reportedChannelName: textWithKeyword(),
guildContextId: keyword(),
resolvedAt: long(),
resolvedByAdminId: keyword(),
publicComment: keyword(),
createdAt: long(),
},
},
},
audit_logs: {
indexName: 'audit_logs',
mappings: {
properties: {
id: keyword(),
logId: keyword(),
adminUserId: keyword(),
targetType: textWithKeyword(),
targetId: textWithKeyword(),
action: textWithKeyword(),
auditLogReason: textWithKeyword(),
createdAt: long(),
},
},
},
guild_members: {
indexName: 'guild_members',
mappings: {
properties: {
id: keyword(),
guildId: keyword(),
userId: textWithKeyword(),
username: textWithKeyword(),
discriminator: textWithKeyword(),
globalName: textWithKeyword(),
nickname: textWithKeyword(),
roleIds: keyword(),
joinedAt: long(),
joinSourceType: integer(),
sourceInviteCode: keyword(),
inviterId: keyword(),
userCreatedAt: long(),
isBot: bool(),
},
},
},
};