mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-10 12:42:44 +01:00
🚧 typeorm
This commit is contained in:
parent
f711a0411c
commit
ae2896fa61
7
Status.ts
Normal file
7
Status.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export type Status = "idle" | "dnd" | "online" | "offline";
|
||||
|
||||
export interface ClientStatus {
|
||||
desktop?: string; // e.g. Windows/Linux/Mac
|
||||
mobile?: string; // e.g. iOS/Android
|
||||
web?: string; // e.g. browser, bot account
|
||||
}
|
11863
util/package-lock.json
generated
11863
util/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,7 @@
|
||||
"dependencies": {
|
||||
"ajv": "^8.5.0",
|
||||
"amqplib": "^0.8.0",
|
||||
"class-validator": "^0.13.1",
|
||||
"dot-prop": "^6.0.1",
|
||||
"env-paths": "^2.2.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
@ -47,7 +48,8 @@
|
||||
"node-fetch": "^2.6.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"sqlite3": "^5.0.2",
|
||||
"ts-transform-json-schema": "^2.0.3",
|
||||
"typeorm": "^0.2.37",
|
||||
"typescript": "^4.1.3"
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,24 @@
|
||||
import "reflect-metadata";
|
||||
import { BaseEntity, Column } from "typeorm";
|
||||
import { BaseEntity, BeforeInsert, BeforeUpdate, Column, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Snowflake } from "../util/Snowflake";
|
||||
import { IsString, validateOrReject } from "class-validator";
|
||||
|
||||
export class BaseClass extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
@Column()
|
||||
id?: string;
|
||||
@IsString()
|
||||
id: string;
|
||||
|
||||
constructor(props?: any) {
|
||||
constructor(props?: any, opts: { id?: string } = {}) {
|
||||
super();
|
||||
BaseClass.assign(props, this, "body.");
|
||||
this.id = opts.id || Snowflake.generate();
|
||||
Object.defineProperties(this, props);
|
||||
}
|
||||
|
||||
private static assign(props: any, object: any, path?: string): any {
|
||||
const expectedType = Reflect.getMetadata("design:type", object, props);
|
||||
console.log(expectedType, object, props, path, typeof object);
|
||||
|
||||
if (typeof object !== typeof props) throw new Error(`Property at ${path} must be`);
|
||||
if (typeof object === "object")
|
||||
return Object.keys(object).map((key) => BaseClass.assign(props[key], object[key], `${path}.${key}`));
|
||||
@BeforeUpdate()
|
||||
@BeforeInsert()
|
||||
async validate() {
|
||||
await validateOrReject(this, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import { Column, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Activity } from "./Activity";
|
||||
import { BaseClass } from "./BaseClass";
|
||||
import { ClientStatus, Status } from "./Status";
|
||||
import { validateOrReject, IsInt, IsEmail, IsPhoneNumber, IsBoolean, IsString, ValidateNested } from "class-validator";
|
||||
|
||||
export const PublicUserProjection = {
|
||||
username: true,
|
||||
@ -16,67 +17,80 @@ export const PublicUserProjection = {
|
||||
};
|
||||
|
||||
export class User extends BaseClass {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: string;
|
||||
|
||||
@Column()
|
||||
@IsString()
|
||||
username: string; // username max length 32, min 2 (should be configurable)
|
||||
|
||||
@Column()
|
||||
@IsInt()
|
||||
discriminator: string; // #0001 4 digit long string from #0001 - #9999
|
||||
|
||||
@Column()
|
||||
@IsString()
|
||||
avatar: string | null; // hash of the user avatar
|
||||
|
||||
@Column()
|
||||
@IsInt()
|
||||
accent_color: number | null; // banner color of user
|
||||
|
||||
@Column()
|
||||
banner: string | null; // hash of the user banner
|
||||
|
||||
@Column()
|
||||
@IsPhoneNumber()
|
||||
phone: string | null; // phone number of the user
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
desktop: boolean; // if the user has desktop app installed
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
mobile: boolean; // if the user has mobile app installed
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
premium: boolean; // if user bought nitro
|
||||
|
||||
@Column()
|
||||
premium_type: number; // nitro level
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
bot: boolean; // if user is bot
|
||||
|
||||
@Column()
|
||||
bio: string; // short description of the user (max 190 chars -> should be configurable)
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
nsfw_allowed: boolean; // if the user is older than 18 (resp. Config)
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
mfa_enabled: boolean; // if multi factor authentication is enabled
|
||||
|
||||
@Column()
|
||||
created_at: Date; // registration date
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
verified: boolean; // if the user is offically verified
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
disabled: boolean; // if the account is disabled
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
deleted: boolean; // if the user was deleted
|
||||
|
||||
@Column()
|
||||
@IsEmail()
|
||||
email: string | null; // email of the user
|
||||
|
||||
@Column()
|
||||
@ -86,15 +100,19 @@ export class User extends BaseClass {
|
||||
public_flags: bigint;
|
||||
|
||||
@Column("simple-array") // string in simple-array must not contain commas
|
||||
@IsString({ each: true })
|
||||
guilds: string[]; // array of guild ids the user is part of
|
||||
|
||||
@Column("simple-json")
|
||||
user_settings: UserSettings;
|
||||
|
||||
@Column("simple-json")
|
||||
user_data: UserData;
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
user_data: {
|
||||
valid_tokens_since: Date; // all tokens with a previous issue date are invalid
|
||||
hash: string; // hash of the password, salt is saved in password (bcrypt)
|
||||
fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts
|
||||
};
|
||||
|
||||
@Column("simple-json")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
presence: {
|
||||
status: Status;
|
||||
activities: Activity[];
|
||||
@ -102,22 +120,76 @@ export class User extends BaseClass {
|
||||
};
|
||||
|
||||
@Column("simple-json")
|
||||
relationships: Relationship[];
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
relationships: {
|
||||
id: string;
|
||||
nickname?: string;
|
||||
type: RelationshipType;
|
||||
}[];
|
||||
|
||||
@Column("simple-json")
|
||||
connected_accounts: ConnectedAccount[];
|
||||
}
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
connected_accounts: {
|
||||
access_token: string;
|
||||
friend_sync: boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
revoked: boolean;
|
||||
show_activity: boolean;
|
||||
type: string;
|
||||
verifie: boolean;
|
||||
visibility: number;
|
||||
}[];
|
||||
|
||||
// @ts-ignore
|
||||
global.User = User;
|
||||
@Column("simple-json")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
user_settings: {
|
||||
afk_timeout: number;
|
||||
allow_accessibility_detection: boolean;
|
||||
animate_emoji: boolean;
|
||||
animate_stickers: number;
|
||||
contact_sync_enabled: boolean;
|
||||
convert_emoticons: boolean;
|
||||
custom_status: {
|
||||
emoji_id: string | null;
|
||||
emoji_name: string | null;
|
||||
expires_at: number | null;
|
||||
text: string | null;
|
||||
};
|
||||
default_guilds_restricted: boolean;
|
||||
detect_platform_accounts: boolean;
|
||||
developer_mode: boolean;
|
||||
disable_games_tab: boolean;
|
||||
enable_tts_command: boolean;
|
||||
explicit_content_filter: number;
|
||||
friend_source_flags: { all: boolean };
|
||||
gateway_connected: boolean;
|
||||
gif_auto_play: boolean;
|
||||
guild_folders: // every top guild is displayed as a "folder"
|
||||
{
|
||||
color: number;
|
||||
guild_ids: string[];
|
||||
id: number;
|
||||
name: string;
|
||||
}[];
|
||||
guild_positions: string[]; // guild ids ordered by position
|
||||
inline_attachment_media: boolean;
|
||||
inline_embed_media: boolean;
|
||||
locale: string; // en_US
|
||||
message_display_compact: boolean;
|
||||
native_phone_integration_enabled: boolean;
|
||||
render_embeds: boolean;
|
||||
render_reactions: boolean;
|
||||
restricted_guilds: string[];
|
||||
show_current_game: boolean;
|
||||
status: "online" | "offline" | "dnd" | "idle";
|
||||
stream_notifications_enabled: boolean;
|
||||
theme: "dark" | "white"; // dark
|
||||
timezone_offset: number; // e.g -60
|
||||
};
|
||||
}
|
||||
|
||||
// Private user data that should never get sent to the client
|
||||
export interface UserData {
|
||||
valid_tokens_since: Date; // all tokens with a previous issue date are invalid
|
||||
hash: string; // hash of the password, salt is saved in password (bcrypt)
|
||||
fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts
|
||||
}
|
||||
|
||||
export interface PublicUser {
|
||||
id: string;
|
||||
discriminator: string;
|
||||
@ -129,72 +201,9 @@ export interface PublicUser {
|
||||
bot: boolean;
|
||||
}
|
||||
|
||||
export interface ConnectedAccount {
|
||||
access_token: string;
|
||||
friend_sync: boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
revoked: boolean;
|
||||
show_activity: boolean;
|
||||
type: string;
|
||||
verifie: boolean;
|
||||
visibility: number;
|
||||
}
|
||||
|
||||
export interface Relationship {
|
||||
id: string;
|
||||
nickname?: string;
|
||||
type: RelationshipType;
|
||||
}
|
||||
|
||||
export enum RelationshipType {
|
||||
outgoing = 4,
|
||||
incoming = 3,
|
||||
blocked = 2,
|
||||
friends = 1,
|
||||
}
|
||||
|
||||
export interface UserSettings {
|
||||
afk_timeout: number;
|
||||
allow_accessibility_detection: boolean;
|
||||
animate_emoji: boolean;
|
||||
animate_stickers: number;
|
||||
contact_sync_enabled: boolean;
|
||||
convert_emoticons: boolean;
|
||||
custom_status: {
|
||||
emoji_id: string | null;
|
||||
emoji_name: string | null;
|
||||
expires_at: number | null;
|
||||
text: string | null;
|
||||
};
|
||||
default_guilds_restricted: boolean;
|
||||
detect_platform_accounts: boolean;
|
||||
developer_mode: boolean;
|
||||
disable_games_tab: boolean;
|
||||
enable_tts_command: boolean;
|
||||
explicit_content_filter: number;
|
||||
friend_source_flags: { all: boolean };
|
||||
gateway_connected: boolean;
|
||||
gif_auto_play: boolean;
|
||||
guild_folders: // every top guild is displayed as a "folder"
|
||||
{
|
||||
color: number;
|
||||
guild_ids: string[];
|
||||
id: number;
|
||||
name: string;
|
||||
}[];
|
||||
guild_positions: string[]; // guild ids ordered by position
|
||||
inline_attachment_media: boolean;
|
||||
inline_embed_media: boolean;
|
||||
locale: string; // en_US
|
||||
message_display_compact: boolean;
|
||||
native_phone_integration_enabled: boolean;
|
||||
render_embeds: boolean;
|
||||
render_reactions: boolean;
|
||||
restricted_guilds: string[];
|
||||
show_current_game: boolean;
|
||||
status: "online" | "offline" | "dnd" | "idle";
|
||||
stream_notifications_enabled: boolean;
|
||||
theme: "dark" | "white"; // dark
|
||||
timezone_offset: number; // e.g -60
|
||||
}
|
||||
|
@ -67,6 +67,12 @@
|
||||
"skipLibCheck": true /* Skip type checking of declaration files. */,
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"plugins": [
|
||||
{
|
||||
"transform": "ts-transform-json-schema",
|
||||
"type": "program"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user