UNPKG

@xrengine/server-core

Version:

Shared components for XREngine server

141 lines (122 loc) 3.55 kB
import { Params } from '@feathersjs/feathers/lib' import { LocationInterface } from '@xrengine/common/src/dbmodels/Location' import { Instance as InstanceInterface } from '@xrengine/common/src/interfaces/Instance' import { Application } from '../../../declarations' import authenticate from '../../hooks/authenticate' import verifyScope from '../../hooks/verify-scope' import logger from '../../ServerLogger' import { Instance } from './instance.class' import instanceDocs from './instance.docs' import hooks from './instance.hooks' import createModel from './instance.model' declare module '@xrengine/common/declarations' { interface ServiceTypes { instance: Instance 'instances-active': { find: ReturnType<typeof getActiveInstancesForScene> } } } type ActiveInstance = { id: string location: string currentUsers: number } // TODO: paginate this export const getActiveInstancesForScene = (app: Application) => async (params: Params & { query: { sceneId: string } }): Promise<ActiveInstance[]> => { const sceneId = params.query!.sceneId if (!sceneId) return [] // get all locationIds for sceneId const locations = (await app.service('location').Model.findAll({ where: { sceneId } })) as LocationInterface[] if (!locations) return [] const instances = ( (await Promise.all( locations.map((location) => { return app.service('instance').Model.findAll({ where: { ended: false, locationId: location.id }, include: [ { model: app.service('location').Model, where: {} } ] }) }) )) as InstanceInterface[] ).flat() // return all active instances for each location const instancesData: ActiveInstance[] = instances .map((instance) => { return { id: instance.id, location: instance.location!.id, currentUsers: instance.currentUsers } }) .filter((a) => !!a) return instancesData } export default (app: Application) => { const options = { Model: createModel(app), paginate: app.get('paginate'), multi: true } /** * Initialize our service with any options it requires and docs */ const event = new Instance(options, app) event.docs = instanceDocs app.use('instance', event) const service = app.service('instance') service.hooks(hooks) /** * A method used to remove specific instance * * @param data * @returns deleted channel */ service.publish('removed', async (data): Promise<any> => { try { const admins = await app.service('user').Model.findAll({ include: [ { model: app.service('scope').Model, where: { type: 'admin:admin' } } ] }) const targetIds = admins.map((admin) => admin.id) // eslint-disable-next-line @typescript-eslint/restrict-template-expressions return await Promise.all( targetIds.map((userId: string) => { return app.channel(`userIds/${userId}`).send({ instance: data }) }) ) } catch (err) { logger.error(err) throw err } }) app.use('instances-active', { find: getActiveInstancesForScene(app) }) app.service('instances-active').hooks({ before: { find: [authenticate(), verifyScope('editor', 'write')] } }) }