Backend: Test channel delete with a custom testing library
This commit is contained in:
parent
a3561ef9b5
commit
1c4418ab58
4
backend/package-lock.json
generated
4
backend/package-lock.json
generated
@ -99,7 +99,7 @@
|
||||
},
|
||||
"node_modules/@accord/ion": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "git+ssh://git@github.com/accord-dot-app/ion.git#590fcd2115f5b7b32bb3a0960a96e8ec21db2d13",
|
||||
"resolved": "git+ssh://git@github.com/accord-dot-app/ion.git#ca90af119f61f503646978b381b17977f10bb90e",
|
||||
"hasInstallScript": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
@ -6906,7 +6906,7 @@
|
||||
"version": "file:src"
|
||||
},
|
||||
"@accord/ion": {
|
||||
"version": "git+ssh://git@github.com/accord-dot-app/ion.git#590fcd2115f5b7b32bb3a0960a96e8ec21db2d13",
|
||||
"version": "git+ssh://git@github.com/accord-dot-app/ion.git#ca90af119f61f503646978b381b17977f10bb90e",
|
||||
"from": "@accord/ion@github:accord-dot-app/ion",
|
||||
"requires": {
|
||||
"@accord/ion": "github:accord-dot-app/ion",
|
||||
|
@ -7,7 +7,7 @@
|
||||
"start:debug": "nodemon --exec 'node --inspect=0.0.0.0:9229 --require ts-node/register src/app.ts' --ext 'ts,yml'",
|
||||
"start:prod": "ts-node-transpile-only src/app.ts",
|
||||
"test": "npm run test:int test:unit",
|
||||
"test:int": "ts-mocha --exit test/int/test.ts",
|
||||
"test:int": "ts-mocha --exit test/e2e/test.ts",
|
||||
"test:unit": "ts-mocha --exit test/unit/**/**.test.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
@ -43,7 +43,6 @@
|
||||
"rate-limit-mongo": "^2.3.1",
|
||||
"re2": "^1.16.0",
|
||||
"socket.io": "^4.0.0",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"striptags": "^3.2.0",
|
||||
"typescript": "^4.2.3",
|
||||
"winston": "^3.3.3"
|
||||
@ -79,6 +78,7 @@
|
||||
"chai-spies": "^1.0.0",
|
||||
"mocha": "^8.2.1",
|
||||
"nodemon": "^2.0.14",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-mocha": "^8.0.0",
|
||||
"ts-node": "^10.4.0",
|
||||
|
@ -19,7 +19,7 @@ export default class Channels extends DBWrapper<string, ChannelDocument> {
|
||||
|
||||
public async create(options: Partial<Entity.Channel>): Promise<ChannelDocument> {
|
||||
return Channel.create({
|
||||
_id: generateSnowflake(),
|
||||
_id: options.id ?? generateSnowflake(),
|
||||
name: 'chat',
|
||||
position: await Channel.countDocuments({ guildId: options.guildId }),
|
||||
type: 'TEXT',
|
||||
|
@ -3,39 +3,36 @@ import DBWrapper from './db-wrapper';
|
||||
import { GuildDocument } from './models/guild';
|
||||
import { GuildMember, GuildMemberDocument } from './models/guild-member';
|
||||
import { Role } from './models/role';
|
||||
import { SelfUserDocument, UserDocument } from './models/user';
|
||||
import { SelfUserDocument, User, UserDocument } from './models/user';
|
||||
import { generateSnowflake } from './snowflake-entity';
|
||||
|
||||
export default class GuildMembers extends DBWrapper<string, GuildMemberDocument> {
|
||||
public async get(id: string | undefined) {
|
||||
const member = await GuildMember.findById(id);
|
||||
if (!member)
|
||||
throw new TypeError('Guild Member Not Found');
|
||||
throw new TypeError('Guild member not found');
|
||||
return member;
|
||||
}
|
||||
|
||||
public async getInGuild(guildId: string | undefined, userId: string | undefined) {
|
||||
const member = await GuildMember.findOne({ guildId, userId });
|
||||
if (!member)
|
||||
throw new TypeError('Guild Member Not Found');
|
||||
throw new TypeError('Guild member not found');
|
||||
return member;
|
||||
}
|
||||
|
||||
public async create(guildId: string, user: SelfUserDocument) {
|
||||
public async create(options: Partial<Entity.GuildMember>) {
|
||||
const member = await GuildMember.create({
|
||||
_id: generateSnowflake(),
|
||||
guildId,
|
||||
userId: user.id,
|
||||
roleIds: [await this.getEveryoneRoleId(guildId)],
|
||||
_id: options.id ?? generateSnowflake(),
|
||||
roleIds: [await this.getEveryoneRoleId(options.guildId!)],
|
||||
...options,
|
||||
});
|
||||
await this.addToUser(user, guildId);
|
||||
|
||||
await this.addGuildToUser(options.userId!, options.guildId!);
|
||||
return member;
|
||||
}
|
||||
|
||||
private async addToUser(user: SelfUserDocument, guildId: string) {
|
||||
user.guildIds.push(guildId);
|
||||
await user.save();
|
||||
private async addGuildToUser(userId: string, guildId: string) {
|
||||
await User.updateOne({ _id: userId }, { $push: { guildIds: guildId } });
|
||||
}
|
||||
|
||||
private async getEveryoneRoleId(guildId: string) {
|
||||
|
@ -12,7 +12,7 @@ export default class Guilds extends DBWrapper<string, GuildDocument> {
|
||||
public async get(id: string | undefined) {
|
||||
const guild = await Guild.findById(id);
|
||||
if (!guild)
|
||||
throw new APIError(404, 'Guild Not Found');
|
||||
throw new APIError(404, 'Guild not found');
|
||||
return guild;
|
||||
}
|
||||
|
||||
@ -20,8 +20,8 @@ export default class Guilds extends DBWrapper<string, GuildDocument> {
|
||||
return await Guild.findOne({ channels: { $in: id } as any });
|
||||
}
|
||||
|
||||
public async create(name: string, owner: SelfUserDocument): Promise<GuildDocument> {
|
||||
const guildId = generateSnowflake();
|
||||
public async create(options: Partial<Entity.Guild>): Promise<GuildDocument> {
|
||||
const guildId = options.id ?? generateSnowflake();
|
||||
|
||||
const [_, systemChannel, __] = await Promise.all([
|
||||
deps.roles.create(guildId, { name: '@everyone' }),
|
||||
@ -31,11 +31,12 @@ export default class Guilds extends DBWrapper<string, GuildDocument> {
|
||||
const [guild, ___] = await Promise.all([
|
||||
Guild.create({
|
||||
_id: guildId,
|
||||
name,
|
||||
ownerId: owner.id,
|
||||
name: 'Unnamed Guild',
|
||||
ownerId: options.ownerId,
|
||||
systemChannelId: systemChannel.id,
|
||||
...options,
|
||||
}),
|
||||
deps.guildMembers.create(guildId, owner),
|
||||
deps.guildMembers.create({ guildId, userId: options.ownerId }),
|
||||
]);
|
||||
|
||||
return guild;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Socket } from 'socket.io';
|
||||
import { Channel } from '../../data/models/channel';
|
||||
import { SelfUserDocument } from '../../data/models/user';
|
||||
|
||||
import { WSGuard } from './ws-guard';
|
||||
|
||||
export class WSRooms {
|
||||
@ -26,7 +25,6 @@ export class WSRooms {
|
||||
|
||||
for (const channel of channels)
|
||||
try {
|
||||
// TODO: TESTME
|
||||
if (channel.type === 'VOICE') continue;
|
||||
|
||||
await deps.wsGuard.validateCanInChannel(client, channel.id, 'READ_MESSAGES');
|
||||
|
@ -43,7 +43,11 @@ export class WebSocket {
|
||||
for (const event of this.events.values())
|
||||
client.on(event.on, async (data: any) => {
|
||||
try {
|
||||
await event.invoke.call(event, this, client, data);
|
||||
const actions = await event.invoke.call(event, this, client, data);
|
||||
for (const action of actions)
|
||||
this.io
|
||||
.to(action.to)
|
||||
.emit(action.emit, action.send);
|
||||
} catch (error) {
|
||||
client.emit('error', { message: (error as Error).message });
|
||||
} finally {
|
||||
|
@ -10,7 +10,7 @@ export default class implements WSEvent<'GUILD_CREATE'> {
|
||||
const userId = ws.sessions.userId(client);
|
||||
|
||||
const user = await deps.users.getSelf(userId);
|
||||
const guild = await deps.guilds.create(name, user);
|
||||
const guild = await deps.guilds.create({ name, ownerId: user.id });
|
||||
const entities = await deps.guilds.getEntities(guild.id);
|
||||
|
||||
await deps.wsRooms.joinGuildRooms(user, client);
|
||||
|
@ -26,7 +26,7 @@ export default class implements WSEvent<'GUILD_MEMBER_ADD'> {
|
||||
const [_, __, member] = await Promise.all([
|
||||
this.handleInvite(invite),
|
||||
deps.wsRooms.joinGuildRooms(selfUser, client),
|
||||
deps.guildMembers.create(guild.id, selfUser),,
|
||||
deps.guildMembers.create({ guildId: guild.id, userId: selfUser.id }),
|
||||
]);
|
||||
const entities = await deps.guilds.getEntities(guild.id);
|
||||
client.emit('GUILD_CREATE', { guild, ...entities } as WS.Args.GuildCreate);
|
||||
|
@ -1,62 +1,38 @@
|
||||
import { Socket } from 'socket.io';
|
||||
import Channels from '../../data/channels';
|
||||
import { SelfUserDocument } from '../../data/models/user';
|
||||
import Users from '../../data/users';
|
||||
|
||||
|
||||
import { WSGuard } from '../modules/ws-guard';
|
||||
import { WSRooms } from '../modules/ws-rooms';
|
||||
import { WebSocket } from '../websocket';
|
||||
import ChannelJoin from './channel-join';
|
||||
import { WSEvent, } from './ws-event';
|
||||
|
||||
export default class implements WSEvent<'READY'> {
|
||||
public on = 'READY' as const;
|
||||
public cooldown = 5;
|
||||
|
||||
constructor(
|
||||
private channelJoinEvent = deps.channelJoin,
|
||||
private guard = deps.wsGuard,
|
||||
private rooms = deps.wsRooms,
|
||||
private users = deps.users,
|
||||
) {}
|
||||
|
||||
public async invoke(ws: WebSocket, client: Socket, { token }: WS.Params.Ready) {
|
||||
const { id: userId } = await this.guard.decodeKey(token);
|
||||
const { id: userId } = await deps.wsGuard.decodeKey(token);
|
||||
if (!userId)
|
||||
throw new TypeError('Invalid User ID');
|
||||
|
||||
ws.sessions.set(client.id, userId);
|
||||
|
||||
const user = await this.users.getSelf(userId);
|
||||
const user = await deps.users.getSelf(userId);
|
||||
|
||||
try {
|
||||
if (user.voice.channelId)
|
||||
await this.channelJoinEvent.invoke(ws, client, {
|
||||
channelId: user.voice.channelId,
|
||||
});
|
||||
await deps.channelJoin.invoke(ws, client, { channelId: user.voice.channelId });
|
||||
} catch {}
|
||||
|
||||
|
||||
await this.handleUser(ws, user);
|
||||
await this.rooms.join(client, user);
|
||||
|
||||
ws.io
|
||||
.to(client.id)
|
||||
.emit('READY', { user } as WS.Args.Ready);
|
||||
}
|
||||
|
||||
private async handleUser(ws: WebSocket, user: SelfUserDocument) {
|
||||
// if (user.status === 'ONLINE') return;
|
||||
|
||||
user.status = 'ONLINE';
|
||||
await user.save();
|
||||
|
||||
ws.io
|
||||
.to(user.guildIds)
|
||||
.emit('PRESENCE_UPDATE', {
|
||||
userId: user.id,
|
||||
status: user.status
|
||||
} as WS.Args.PresenceUpdate);
|
||||
await deps.wsRooms.join(client, user);
|
||||
|
||||
return [{
|
||||
emit: 'PRESENCE_UPDATE',
|
||||
to: user.guildIds,
|
||||
send: { userId: user.id, status: user.status },
|
||||
}, {
|
||||
emit: 'READY',
|
||||
to: [client.id],
|
||||
send: { user },
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ type OnWS = WS.To & WS.On;
|
||||
export interface WSEvent<K extends keyof OnWS> {
|
||||
on: K;
|
||||
cooldown?: number;
|
||||
|
||||
invoke: (ws: WebSocket, client: Socket, params: OnWS[K]) => Promise<WSAction<keyof WS.From>[]>;
|
||||
}
|
||||
|
||||
|
80
backend/test/e2e/ws/channel-delete.test.ts
Normal file
80
backend/test/e2e/ws/channel-delete.test.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import '@accord/types';
|
||||
import { given, test } from '@accord/ion';
|
||||
import { Channel } from '@accord/backend/data/models/channel';
|
||||
import { Guild } from '@accord/backend/data/models/guild';
|
||||
import { SelfUserDocument, User } from '@accord/backend/data/models/user';
|
||||
import { generateSnowflake } from '@accord/backend/data/snowflake-entity';
|
||||
import io from 'socket.io-client';
|
||||
|
||||
const socket = (io as any).connect(process.env.ROOT_ENDPOINT, {
|
||||
secure: true,
|
||||
path: `/ws`,
|
||||
transports: ['websocket', 'polling', 'flashsocket'],
|
||||
});
|
||||
socket.io.on('open', () => console.log('Connected to WS Server'));
|
||||
|
||||
test(channelDelete, () => {
|
||||
const channelId = generateSnowflake();
|
||||
const guildId = generateSnowflake();
|
||||
|
||||
let channel: Entity.Channel;
|
||||
let guild: Entity.Guild;
|
||||
let ownerUser: SelfUserDocument;
|
||||
|
||||
beforeEach(async function () {
|
||||
await Promise.all([
|
||||
Channel.deleteMany(),
|
||||
Guild.deleteMany(),
|
||||
User.deleteMany(),
|
||||
]);
|
||||
|
||||
ownerUser = await deps.users.create({
|
||||
email: 'user1@example.com',
|
||||
username: 'Test User',
|
||||
password: 'doesnotmatter',
|
||||
});
|
||||
guild = await deps.guilds.create({
|
||||
id: guildId,
|
||||
name: 'Test Guild',
|
||||
ownerId: ownerUser.id,
|
||||
});
|
||||
channel = await deps.channels.create({ id: channelId, guildId });
|
||||
|
||||
const token = await deps.users.createToken(ownerUser);
|
||||
socket.emit('READY', { token });
|
||||
});
|
||||
|
||||
// @accord/ion: before tests must go above
|
||||
given({ channelId })
|
||||
.message('Channel exists, user is not in guild')
|
||||
.before(setRandomUser)
|
||||
.rejectWith('Guild member not found');
|
||||
|
||||
given({})
|
||||
.message('No args, rejected')
|
||||
.rejectWith('Channel not found');
|
||||
given({ channelId: generateSnowflake() })
|
||||
.message('Non existing channel, rejected')
|
||||
.rejectWith('Channel not found');
|
||||
given({ channelId })
|
||||
.message('Channel exists, user is guild owner')
|
||||
.resolveWith({ channelId, guildId });
|
||||
|
||||
async function setRandomUser() {
|
||||
const randomUser = await deps.users.create({
|
||||
email: 'user2@example.com',
|
||||
username: 'Test User 2',
|
||||
password: 'doesnotmatter',
|
||||
});
|
||||
const token = await deps.users.createToken(randomUser);
|
||||
socket.emit('READY', { token });
|
||||
}
|
||||
});
|
||||
|
||||
function channelDelete(args: WS.To['CHANNEL_DELETE']) {
|
||||
return new Promise((resolve, reject) => {
|
||||
socket.on('CHANNEL_DELETE', (res) => resolve(res));
|
||||
socket.on('error', (error) => reject(error));
|
||||
socket.emit('CHANNEL_DELETE', args);
|
||||
});
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import '@accord/types';
|
||||
import { given, test } from '@accord/ion';
|
||||
import { Channel } from '@accord/backend/data/models/channel';
|
||||
import { Guild } from '@accord/backend/data/models/guild';
|
||||
import ChannelDelete from '@accord/backend/ws/ws-events/channel-delete';
|
||||
import { WebSocket } from '@accord/backend/ws/websocket';
|
||||
import { SelfUserDocument, User } from '@accord/backend/data/models/user';
|
||||
import { generateSnowflake } from '@accord/backend/data/snowflake-entity';
|
||||
|
||||
test(channelDelete, () => {
|
||||
let channel: Entity.Channel;
|
||||
let guild: Entity.Guild;
|
||||
let ownerUser: SelfUserDocument;
|
||||
|
||||
beforeEach(async () => {
|
||||
await Promise.all([
|
||||
Channel.deleteMany(),
|
||||
Guild.deleteMany(),
|
||||
User.deleteMany(),
|
||||
]);
|
||||
|
||||
ownerUser = await deps.users.create({
|
||||
email: 'user1@example.com',
|
||||
username: 'Test User',
|
||||
password: 'doesnotmatter',
|
||||
});
|
||||
guild = await deps.guilds.create('Test Guild', ownerUser);
|
||||
channel = await deps.channels.create({ guildId: guild.id });
|
||||
})
|
||||
|
||||
// given({ channelId: channel.id })
|
||||
// .before(async () => ownerUser = await deps.users.create({
|
||||
// email: 'user2@example.com',
|
||||
// username: 'Test User 2',
|
||||
// password: 'doesnotmatter',
|
||||
// }))
|
||||
// .rejectWith('Missing Permissions');
|
||||
|
||||
// given({ channelId: channel.id }).resolveWith([{
|
||||
// emit: 'CHANNEL_DELETE',
|
||||
// to: channel.id,
|
||||
// send: { channelId: channel.id },
|
||||
// }]);
|
||||
|
||||
given({}).rejectWith('Channel not found');
|
||||
given({ channelId: generateSnowflake() }).rejectWith('Channel not found');
|
||||
});
|
||||
|
||||
async function channelDelete(args: WS.To['CHANNEL_DELETE']) {
|
||||
const event = new ChannelDelete();
|
||||
return event.invoke(new WebSocket(), {} as any, args);
|
||||
}
|
||||
|
55
frontend/package-lock.json
generated
55
frontend/package-lock.json
generated
@ -8,7 +8,7 @@
|
||||
"name": "accord-frontend",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@accord/types": "file:./types",
|
||||
"@accord/types": "file:../types",
|
||||
"@craco/craco": "^5.9.0",
|
||||
"@dvhb/craco-extend-scope": "^1.0.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||
@ -77,8 +77,15 @@
|
||||
"fsevents": "^2.3.2"
|
||||
}
|
||||
},
|
||||
"../types": {
|
||||
"name": "@accord/types",
|
||||
"dependencies": {
|
||||
"@accord/backend": "file:../backend/src",
|
||||
"@types/winston": "^2.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@accord/types": {
|
||||
"resolved": "types",
|
||||
"resolved": "../types",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@ -14231,9 +14238,9 @@
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
},
|
||||
"node_modules/json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
@ -14283,18 +14290,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
||||
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
|
||||
"dev": true,
|
||||
"engines": [
|
||||
"node >=0.6.0"
|
||||
],
|
||||
"dependencies": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"json-schema": "0.4.0",
|
||||
"verror": "1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jss": {
|
||||
@ -26547,11 +26554,17 @@
|
||||
"resolved": "https://registry.npmjs.org/zalgo-promise/-/zalgo-promise-1.0.48.tgz",
|
||||
"integrity": "sha512-LLHANmdm53+MucY9aOFIggzYtUdkSBFxUsy4glTTQYNyK6B3uCPWTbfiGvSrEvLojw0mSzyFJ1/RRLv+QMNdzQ=="
|
||||
},
|
||||
"types": {}
|
||||
"types": {
|
||||
"extraneous": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@accord/types": {
|
||||
"version": "file:types"
|
||||
"version": "file:../types",
|
||||
"requires": {
|
||||
"@accord/backend": "file:../backend/src",
|
||||
"@types/winston": "^2.4.4"
|
||||
}
|
||||
},
|
||||
"@babel/code-frame": {
|
||||
"version": "7.16.0",
|
||||
@ -37428,9 +37441,9 @@
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
@ -37472,14 +37485,14 @@
|
||||
}
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
||||
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"json-schema": "0.4.0",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"homepage": "https://accord.app",
|
||||
"dependencies": {
|
||||
"@accord/types": "file:./types",
|
||||
"@accord/types": "file:../types",
|
||||
"@craco/craco": "^5.9.0",
|
||||
"@dvhb/craco-extend-scope": "^1.0.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.35",
|
||||
|
@ -9,7 +9,6 @@ import PrivateRoute from './routing/private-route';
|
||||
import NotFoundPage from './pages/not-found-page';
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import fetchEntities from '../store/actions/fetch-entities';
|
||||
import { ready } from '../store/auth';
|
||||
import { initPings } from '../store/pings';
|
||||
import VerifyPage from './pages/auth/verify-page';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import '@accord/types';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './components/app';
|
||||
|
@ -1,3 +1,4 @@
|
||||
import '@accord/types';
|
||||
import io from 'socket.io-client';
|
||||
|
||||
const ws = (io as any).connect(process.env.REACT_APP_ROOT_API_URL, {
|
||||
|
@ -6,6 +6,7 @@ declare global {
|
||||
MONGO_URI: string;
|
||||
NODE_ENV: 'dev' | 'prod';
|
||||
PORT: string;
|
||||
ROOT_ENDPOINT: string;
|
||||
WEBSITE_URL: string;
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,8 @@ declare namespace WS {
|
||||
export interface ChannelDelete {
|
||||
/** ID of the channel to delete. */
|
||||
channelId: string;
|
||||
/** ID of the guild that the channel was in. */
|
||||
guildId: string;
|
||||
}
|
||||
export interface ChannelUpdate {
|
||||
/** ID of the channel to update. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user