Skip to content

Commit

Permalink
feat: add websocket handler #194
Browse files Browse the repository at this point in the history
  • Loading branch information
Geoffroy Empain committed Mar 8, 2021
1 parent feb9efb commit 2aad514
Show file tree
Hide file tree
Showing 18 changed files with 222 additions and 191 deletions.
4 changes: 1 addition & 3 deletions src/commons/express-joi/params.ts
Expand Up @@ -7,9 +7,7 @@ export function params($schema: AnySchema) {
return (req: Request, res: Response, next: NextFunction) => {
$schema
.validateAsync(req.params, JOI_OPTIONS)
.then(value => {
// req.params = value;
// console.log(req.params, value);
.then(() => {
next();
})
.catch(err => {
Expand Down
4 changes: 2 additions & 2 deletions src/entities/orgs/handlers/create-org.ts
Expand Up @@ -34,7 +34,7 @@ async function handler(req: Request, res: Response): Promise<void> {
hooks: [],
};
await Orgs().insertOne(org);
emitEvent(EventType.user_org_created, {
emitEvent(EventType.org_created, {
org,
user,
});
Expand Down Expand Up @@ -68,7 +68,7 @@ async function handler(req: Request, res: Response): Promise<void> {
hooks: [],
};
await Teams().insertOne(team);
emitEvent(EventType.org_team_added, {
emitEvent(EventType.team_added, {
org,
team,
});
Expand Down
2 changes: 1 addition & 1 deletion src/entities/orgs/handlers/teams/create-team.ts
Expand Up @@ -39,7 +39,7 @@ async function handler(req: Request, res: Response): Promise<void> {

await Teams().insertOne(team);

emitEvent(EventType.org_team_added, {
emitEvent(EventType.team_added, {
org: await Orgs().findOne({
_id: orgId,
}),
Expand Down
2 changes: 1 addition & 1 deletion src/entities/teams/handlers/sites/create-site.ts
Expand Up @@ -54,7 +54,7 @@ async function handler(req: Request, res: Response): Promise<void> {
logger.error(err);
});

emitEvent(EventType.team_site_added, {
emitEvent(EventType.site_added, {
team: await Teams().findOne({
_id: teamId,
}),
Expand Down
14 changes: 2 additions & 12 deletions src/entities/teams/handlers/sites/list-team-sites.spec.ts
Expand Up @@ -44,11 +44,7 @@ describe('listTeamSites', () => {
countDocuments: jest.fn().mockReturnValue(Promise.resolve(2)),
find: jest.fn().mockReturnValue({
sort: sort.mockReturnValue({
skip: skip.mockReturnValue({
limit: limit.mockReturnValue({
toArray: toArray.mockReturnValue([{ id: 1 }, { id: 2 }]),
}),
}),
toArray: toArray.mockReturnValue([{ id: 1 }, { id: 2 }]),
}),
}),
});
Expand All @@ -59,15 +55,9 @@ describe('listTeamSites', () => {
.send();

expect(response.status).toEqual(200);
expect(response.body).toEqual({
items: [{ id: 1 }, { id: 2 }],
count: 2,
});
expect(sites.countDocuments).toHaveBeenCalledWith({ teamId: 'team-id' });
expect(response.body).toEqual([{ id: 1 }, { id: 2 }]);
expect(sites.find).toHaveBeenCalledWith({ teamId: 'team-id' });
expect(sort).toHaveBeenCalledWith({ updatedAt: -1 });
expect(skip).toHaveBeenCalledWith(0);
expect(limit).toHaveBeenCalledWith(10);
expect(toArray).toHaveBeenCalled();
expect(serializeSite.mock.calls.map(call => call.slice(0, 1))).toEqual([
[{ id: 1 }],
Expand Down
32 changes: 5 additions & 27 deletions src/entities/teams/handlers/sites/list-team-sites.ts
@@ -1,17 +1,14 @@
import { Request, Response } from 'express';
import { getPagination, pageResponse, pageValidators } from '../../../../utils/get-pagination';
import { wrapAsyncMiddleware } from '../../../../commons/utils/wrap-async-middleware';
import { object, string } from 'joi';
import { query } from '../../../../commons/express-joi/query';
import { Site, Sites } from '../../../sites/site';
import { Sites } from '../../../sites/site';
import { params } from '../../../../commons/express-joi/params';
import { FilterQuery } from 'mongodb';
import { canReadTeamGuard } from '../../guards/can-read-team-guard';
import { teamExistsGuard } from '../../guards/team-exists-guard';
import { serializeSite } from '../../../sites/serialize-site';

const validators = [
...pageValidators,
params(object({
teamId: string().optional(),
})),
Expand All @@ -21,37 +18,18 @@ const validators = [
];

async function handler(req: Request, res: Response): Promise<void> {
const pagination = getPagination(req);
const { teamId } = req.params;
const { search } = req.query;

const dbQuery: FilterQuery<Site> = {
teamId,
...(
search
? {
$text: {
$search: search,
},
}
: undefined as any
),
};

const count = await Sites().countDocuments(dbQuery);

const sites = await Sites()
.find(dbQuery)
.find({
teamId,
})
.sort({
updatedAt: -1,
})
.skip(pagination.offset)
.limit(pagination.size)
.toArray();

const json = sites.map(serializeSite);

res.json(pageResponse(json, count));
res.json(sites.map(serializeSite));
}

export const listTeamSites = [
Expand Down
5 changes: 2 additions & 3 deletions src/events/emit-event.ts
@@ -1,13 +1,12 @@
import { Logger } from '../commons/logger/logger';
import { hookEventHandler } from '../hooks/hook-event-handler';
import { socketEventHandler } from '../socket/socket-event-handler';
import { handleSocketEvent } from '../socket/handle-socket-event';
import { EventData } from './event-data';

const logger = new Logger('meli.api:emitEvent');

export function emitEvent<T extends keyof EventData>(type: T, data: EventData[T]): void {
logger.debug(type, data);
hookEventHandler(type, data);
// ui feedback, live list updates etc
socketEventHandler(type, data);
handleSocketEvent(type, data);
}
6 changes: 3 additions & 3 deletions src/events/event-data.ts
Expand Up @@ -201,7 +201,7 @@ export interface EventData {
[EventType.user_api_token_created]: UserApiTokenCreatedEventData,
[EventType.user_api_token_updated]: UserApiTokenUpdatedEventData,
[EventType.user_api_token_deleted]: UserApiTokenDeletedEventData,
[EventType.user_org_created]: UserOrgCreatedEventData,
[EventType.org_created]: UserOrgCreatedEventData,
[EventType.org_updated]: OrgUpdatedEventData,
[EventType.org_logo_set]: OrgEventData,
[EventType.org_logo_removed]: OrgEventData,
Expand All @@ -215,7 +215,7 @@ export interface EventData {
[EventType.org_hook_created]: OrgHookCreatedEventData,
[EventType.org_hook_updated]: OrgHookUpdatedEventData,
[EventType.org_hook_deleted]: OrgHookDeletedEventData,
[EventType.org_team_added]: OrgTeamAddedEventData,
[EventType.team_added]: OrgTeamAddedEventData,
[EventType.team_updated]: TeamUpdatedEventData,
[EventType.team_deleted]: TeamDeletedEventData,
[EventType.team_logo_set]: TeamEventData,
Expand All @@ -225,7 +225,7 @@ export interface EventData {
[EventType.team_hook_created]: TeamHookCreatedEventData,
[EventType.team_hook_updated]: TeamHookUpdatedEventData,
[EventType.team_hook_deleted]: TeamHookDeletedEventData,
[EventType.team_site_added]: TeamSiteAddedEventData,
[EventType.site_added]: TeamSiteAddedEventData,
[EventType.site_updated]: SiteUpdatedEventData,
[EventType.site_deleted]: SiteDeletedEventData,
[EventType.site_logo_set]: SiteEventData,
Expand Down
6 changes: 3 additions & 3 deletions src/events/event-type.ts
Expand Up @@ -2,7 +2,7 @@ export enum EventType {
user_api_token_created = 'user_api_token_created',
user_api_token_updated = 'user_api_token_updated',
user_api_token_deleted = 'user_api_token_deleted',
user_org_created = 'user_org_created',
org_created = 'org_created',
org_updated = 'org_updated',
org_logo_set = 'org_logo_set',
org_logo_removed = 'org_logo_removed',
Expand All @@ -16,7 +16,7 @@ export enum EventType {
org_hook_created = 'org_hook_created',
org_hook_updated = 'org_hook_updated',
org_hook_deleted = 'org_hook_deleted',
org_team_added = 'org_team_added',
team_added = 'team_added',
team_updated = 'team_updated',
team_deleted = 'team_deleted',
team_logo_set = 'team_logo_set',
Expand All @@ -26,7 +26,7 @@ export enum EventType {
team_hook_created = 'team_hook_created',
team_hook_updated = 'team_hook_updated',
team_hook_deleted = 'team_hook_deleted',
team_site_added = 'team_site_added',
site_added = 'site_added',
site_updated = 'site_updated',
site_logo_set = 'site_logo_set',
site_logo_removed = 'site_logo_removed',
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/get-hooks-for-event.ts
Expand Up @@ -25,7 +25,7 @@ export async function getHooksForEvent<T extends keyof EventData>(eventType: T,
case EventType.user_api_token_created:
case EventType.user_api_token_updated:
case EventType.user_api_token_deleted:
case EventType.user_org_created:
case EventType.org_created:
return (data as UserEventData).user.hooks;
case EventType.org_updated:
case EventType.org_invite_added:
Expand All @@ -38,7 +38,7 @@ export async function getHooksForEvent<T extends keyof EventData>(eventType: T,
case EventType.org_hook_created:
case EventType.org_hook_updated:
case EventType.org_hook_deleted:
case EventType.org_team_added:
case EventType.team_added:
org = (data as OrgEventData).org;
owner = await Users().findOne({
_id: org.ownerId,
Expand All @@ -54,7 +54,7 @@ export async function getHooksForEvent<T extends keyof EventData>(eventType: T,
case EventType.team_hook_created:
case EventType.team_hook_updated:
case EventType.team_hook_deleted:
case EventType.team_site_added:
case EventType.site_added:
team = (data as TeamEventData).team;
org = await Orgs().findOne({
_id: team.orgId,
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/handlers/email/get-message-for-event.ts
Expand Up @@ -18,7 +18,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
subject: 'User api token deleted',
text: `Api token named ${apiToken.name} was deleted for user ${user.name}.`,
}),
[EventType.user_org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => ({
[EventType.org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => ({
subject: 'User org created',
text: `Organization ${org.name} was created for user ${user.name}.`,
}),
Expand Down Expand Up @@ -74,7 +74,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
subject: 'Org hook deleted',
text: `Hook ${hook.name} of type ${hook.type} from organization ${org.name} was deleted.`,
}),
[EventType.org_team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => ({
[EventType.team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => ({
subject: 'Org team added',
text: `Team ${team.name} was added to organization ${org.name}.`,
}),
Expand Down Expand Up @@ -114,7 +114,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
subject: 'Team hook deleted',
text: `Hook ${hook.name} of type ${hook.type} was removed from team ${team.name}.`,
}),
[EventType.team_site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => ({
[EventType.site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => ({
subject: 'Team site added',
text: `Site ${site.name} was added to team ${team.name}. View it live here: ${getSiteUrl(site)}. `,
}),
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/handlers/mattermost/get-message-for-event.ts
Expand Up @@ -15,7 +15,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
[EventType.user_api_token_deleted]: ({ user, apiToken }: EventData.UserApiTokenDeletedEventData) => (
getMattermostMessage(`Api token named **${apiToken.name}** was deleted for user **${user.name}**.`)
),
[EventType.user_org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => (
[EventType.org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => (
getMattermostMessage(`Organization **${org.name}** was created for user **${user.name}**.`)
),
[EventType.org_updated]: ({ org }: EventData.OrgUpdatedEventData) => (
Expand Down Expand Up @@ -57,7 +57,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
[EventType.org_hook_deleted]: ({ org, hook }: EventData.OrgHookDeletedEventData) => (
getMattermostMessage(`Hook **${hook.name}** of type **${hook.type}** from organization **${org.name}** was deleted.`)
),
[EventType.org_team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => (
[EventType.team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => (
getMattermostMessage(`Team **${team.name}** was added to organization **${org.name}**.`)
),
[EventType.team_updated]: ({ team }: EventData.TeamUpdatedEventData) => (
Expand Down Expand Up @@ -87,7 +87,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
[EventType.team_hook_deleted]: ({ team, hook }: EventData.TeamHookDeletedEventData) => (
getMattermostMessage(`Hook **${hook.name}** of type **${hook.type}** was removed from team **${team.name}**.`)
),
[EventType.team_site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => (
[EventType.site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => (
getMattermostMessage(`
Site **${site.name}** was added to team **${team.name}**. View it live [here](${getSiteUrl(site)}). `)
),
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/handlers/slack/get-message-for-event.ts
Expand Up @@ -24,7 +24,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
`Api token named **${apiToken.name}** was deleted for user **${user.name}**.`,
)
),
[EventType.user_org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => (
[EventType.org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => (
getSlackMessage(
'User org created',
`Organization **${org.name}** was created for user **${user.name}**.`,
Expand Down Expand Up @@ -108,7 +108,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
`Hook **${hook.name}** of type **${hook.type}** from organization **${org.name}** was deleted.`,
)
),
[EventType.org_team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => (
[EventType.team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => (
getSlackMessage(
'Org team added',
`Team **${team.name}** was added to organization **${org.name}**.`,
Expand Down Expand Up @@ -168,7 +168,7 @@ export const getMessageForEvent: { [eventType in keyof EventData.EventData]: (da
`Hook **${hook.name}** of type **${hook.type}** was removed from team **${team.name}**.`,
)
),
[EventType.team_site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => (
[EventType.site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => (
getSlackMessage(
'Team site added',
`Site **${site.name}** was added to team **${team.name}**. View it live [here](${getSiteUrl(site)}). `,
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/handlers/web/get-payload.ts
Expand Up @@ -156,7 +156,7 @@ export const getPayload: { [eventType in keyof EventData.EventData]: (data: any)
user: serializeUser(user),
apiToken: serializeApiToken(apiToken),
}),
[EventType.user_org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => ({
[EventType.org_created]: ({ user, org }: EventData.UserOrgCreatedEventData) => ({
user: serializeUser(user),
org: serializeOrg(org),
}),
Expand Down Expand Up @@ -209,7 +209,7 @@ export const getPayload: { [eventType in keyof EventData.EventData]: (data: any)
org: serializeOrg(org),
hook: serializeHook(hook),
}),
[EventType.org_team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => ({
[EventType.team_added]: ({ org, team }: EventData.OrgTeamAddedEventData) => ({
org: serializeOrg(org),
team: serializeTeam(team),
}),
Expand Down Expand Up @@ -245,7 +245,7 @@ export const getPayload: { [eventType in keyof EventData.EventData]: (data: any)
team: serializeTeam(team),
hook: serializeHook(hook),
}),
[EventType.team_site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => ({
[EventType.site_added]: ({ team, site }: EventData.TeamSiteAddedEventData) => ({
team: serializeTeam(team),
site: serializeSite(site),
}),
Expand Down
18 changes: 18 additions & 0 deletions src/socket/handle-socket-event.ts
@@ -0,0 +1,18 @@
import { EventData } from '../events/event-data';
import { Logger } from '../commons/logger/logger';
import { messageBuilders } from './message-builders';
import { Io } from './create-io-server';

const logger = new Logger('meli.api:handleSocketEvent');

export function handleSocketEvent<T extends keyof EventData>(eventType: T, data: EventData[T]): void {
const messageBuilder = messageBuilders[eventType];

if (!messageBuilder) {
logger.debug('no message builder for', eventType);
}

const { room, data: serializedData } = messageBuilder(data);

Io.server.to(room).emit(eventType, serializedData);
}

0 comments on commit 2aad514

Please sign in to comment.