diff --git a/packages/server/modules/activitystream/index.ts b/packages/server/modules/activitystream/index.ts index 0b97221a18..cbb8c74ab0 100644 --- a/packages/server/modules/activitystream/index.ts +++ b/packages/server/modules/activitystream/index.ts @@ -24,7 +24,6 @@ import { acquireTaskLockFactory, releaseTaskLockFactory } from '@/modules/core/repositories/scheduledTasks' -import { UsersEmitter, UsersEvents } from '@/modules/core/events/usersEmitter' import { Knex } from 'knex' import { onServerAccessRequestCreatedFactory, @@ -40,7 +39,8 @@ import { isProjectResourceTarget } from '@/modules/serverinvites/helpers/core' import { publish } from '@/modules/shared/utils/subscriptions' import { isStreamAccessRequest } from '@/modules/accessrequests/repositories' import { ServerInvitesEvents } from '@/modules/serverinvites/domain/events' -import { ProjectEvents, ProjectsEmitter } from '@/modules/core/events/projectsEmitter' +import { ProjectEvents } from '@/modules/core/domain/projects/events' +import { UserEvents } from '@/modules/core/domain/users/events' let scheduledTask: ReturnType | null = null let quitEventListeners: Optional<() => void> = undefined @@ -57,8 +57,8 @@ const initializeEventListeners = ({ db: Knex }) => { const quitCbs = [ - UsersEmitter.listen( - UsersEvents.Created, + eventBus.listen( + UserEvents.Created, // this activity will always go in the main DB onUserCreatedFactory({ saveActivity: saveActivityFactory({ db }) }) ), @@ -90,12 +90,20 @@ const initializeEventListeners = ({ getStream: getStreamFactory({ db }) })(payload) }), - ProjectsEmitter.listen(ProjectEvents.Created, async ({ ownerId, project }) => { - await addStreamCreatedActivityFactory({ - saveActivity: saveActivityFactory({ db }), - publish - })({ streamId: project.id, creatorId: ownerId, stream: project, input: project }) - }) + eventBus.listen( + ProjectEvents.Created, + async ({ payload: { ownerId, project } }) => { + await addStreamCreatedActivityFactory({ + saveActivity: saveActivityFactory({ db }), + publish + })({ + streamId: project.id, + creatorId: ownerId, + stream: project, + input: project + }) + } + ) ] return () => quitCbs.forEach((quit) => quit()) diff --git a/packages/server/modules/activitystream/services/eventListener.ts b/packages/server/modules/activitystream/services/eventListener.ts index 2a979bc664..209d26d9fb 100644 --- a/packages/server/modules/activitystream/services/eventListener.ts +++ b/packages/server/modules/activitystream/services/eventListener.ts @@ -14,7 +14,7 @@ import { SaveActivity } from '@/modules/activitystream/domain/operations' import { GetStream } from '@/modules/core/domain/streams/operations' -import { UsersEvents, UsersEventsPayloads } from '@/modules/core/events/usersEmitter' +import { UserEvents } from '@/modules/core/domain/users/events' import { ServerInvitesEvents, ServerInvitesEventsPayloads @@ -23,11 +23,12 @@ import { isProjectResourceTarget, resolveTarget } from '@/modules/serverinvites/helpers/core' +import { EventPayload } from '@/modules/shared/services/eventBus' export const onUserCreatedFactory = ({ saveActivity }: { saveActivity: SaveActivity }) => - async (payload: UsersEventsPayloads[UsersEvents.Created]) => { - const { user } = payload + async (payload: EventPayload) => { + const { user } = payload.payload await saveActivity({ streamId: null, diff --git a/packages/server/modules/activitystream/tests/activity.spec.js b/packages/server/modules/activitystream/tests/activity.spec.js index 890365eb1f..4d79869ccb 100644 --- a/packages/server/modules/activitystream/tests/activity.spec.js +++ b/packages/server/modules/activitystream/tests/activity.spec.js @@ -51,7 +51,6 @@ const { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } = require('@/modules/serverinvites/repositories/serverInvites') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { createPersonalAccessTokenFactory } = require('@/modules/core/services/tokens') const { storePersonalApiTokenFactory, @@ -65,6 +64,7 @@ const { storeSingleObjectIfNotFoundFactory, storeClosuresIfNotFoundFactory } = require('@/modules/core/repositories/objects') +const { getEventBus } = require('@/modules/shared/services/eventBus') const getUser = getUserFactory({ db }) const getUserActivity = getUserActivityFactory({ db }) @@ -109,7 +109,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ diff --git a/packages/server/modules/activitystream/tests/activitySummary.spec.ts b/packages/server/modules/activitystream/tests/activitySummary.spec.ts index 5c699b64ba..e5363d3a37 100644 --- a/packages/server/modules/activitystream/tests/activitySummary.spec.ts +++ b/packages/server/modules/activitystream/tests/activitySummary.spec.ts @@ -35,7 +35,6 @@ import { import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/services/coreResourceCollection' import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' import { getEventBus } from '@/modules/shared/services/eventBus' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { createBranchFactory } from '@/modules/core/repositories/branches' import { getUserFactory, getUsersFactory } from '@/modules/core/repositories/users' import { getServerInfoFactory } from '@/modules/core/repositories/server' @@ -78,7 +77,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const deleteStream = deleteStreamFactory({ db }) diff --git a/packages/server/modules/auth/index.ts b/packages/server/modules/auth/index.ts index 5efea8609d..0621b35bd8 100644 --- a/packages/server/modules/auth/index.ts +++ b/packages/server/modules/auth/index.ts @@ -52,7 +52,6 @@ import { findEmailFactory, findPrimaryEmailForUserFactory } from '@/modules/core/repositories/userEmails' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' @@ -60,6 +59,7 @@ import { renderEmail } from '@/modules/emails/services/emailRendering' import { sendEmail } from '@/modules/emails/services/sending' import { getServerInfoFactory } from '@/modules/core/repositories/server' import { initializeEventListenerFactory } from '@/modules/auth/services/postAuth' +import { getEventBus } from '@/modules/shared/services/eventBus' const findEmail = findEmailFactory({ db }) const requestNewEmailVerification = requestNewEmailVerificationFactory({ @@ -86,7 +86,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const findOrCreateUser = findOrCreateUserFactory({ @@ -158,7 +158,7 @@ export const init: SpeckleModule['init'] = async (app, isInitial) => { // Listen to event emitters if (isInitial) { const initializeEventListener = initializeEventListenerFactory({ - usersEventsListener: UsersEmitter.listen, + eventBus: getEventBus(), logger: authLogger }) initializeEventListener() diff --git a/packages/server/modules/auth/services/postAuth.ts b/packages/server/modules/auth/services/postAuth.ts index 8c93e7b053..f2091b7cfe 100644 --- a/packages/server/modules/auth/services/postAuth.ts +++ b/packages/server/modules/auth/services/postAuth.ts @@ -3,23 +3,20 @@ import { addToMailchimpAudience, triggerMailchimpCustomerJourney } from '@/modules/auth/services/mailchimp' -import { - UsersEvents, - UsersEventsListener, - UsersEventsPayloads -} from '@/modules/core/events/usersEmitter' +import { UserEvents } from '@/modules/core/domain/users/events' import { enableMixpanel, getMailchimpNewsletterIds, getMailchimpOnboardingIds, getMailchimpStatus } from '@/modules/shared/helpers/envHelper' +import { EventBus, EventPayload } from '@/modules/shared/services/eventBus' import { mixpanel } from '@/modules/shared/utils/mixpanel' const onUserCreatedFactory = (deps: { logger: Logger }) => - async (payload: UsersEventsPayloads[UsersEvents.Created]) => { - const { user, signUpCtx } = payload + async (payload: EventPayload) => { + const { user, signUpCtx } = payload.payload try { // Send event to MP @@ -59,10 +56,9 @@ const onUserCreatedFactory = } export const initializeEventListenerFactory = - (deps: { usersEventsListener: UsersEventsListener; logger: Logger }) => () => { + (deps: { eventBus: EventBus; logger: Logger }) => () => { const onUserCreated = onUserCreatedFactory(deps) - - const cbs = [deps.usersEventsListener(UsersEvents.Created, onUserCreated)] + const cbs = [deps.eventBus.listen(UserEvents.Created, onUserCreated)] return () => cbs.forEach((cb) => cb()) } diff --git a/packages/server/modules/auth/tests/apps.graphql.spec.js b/packages/server/modules/auth/tests/apps.graphql.spec.js index 6ca2252308..6f651fde0c 100644 --- a/packages/server/modules/auth/tests/apps.graphql.spec.js +++ b/packages/server/modules/auth/tests/apps.graphql.spec.js @@ -52,7 +52,6 @@ const { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } = require('@/modules/serverinvites/repositories/serverInvites') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { storeApiTokenFactory, storeTokenScopesFactory, @@ -61,6 +60,7 @@ const { storePersonalApiTokenFactory } = require('@/modules/core/repositories/tokens') const { getServerInfoFactory } = require('@/modules/core/repositories/server') +const { getEventBus } = require('@/modules/shared/services/eventBus') let sendRequest let server @@ -109,7 +109,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ storeApiToken: storeApiTokenFactory({ db }), diff --git a/packages/server/modules/auth/tests/apps.spec.js b/packages/server/modules/auth/tests/apps.spec.js index 7634ca68a8..47b583ab61 100644 --- a/packages/server/modules/auth/tests/apps.spec.js +++ b/packages/server/modules/auth/tests/apps.spec.js @@ -62,7 +62,6 @@ const { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } = require('@/modules/serverinvites/repositories/serverInvites') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { storeApiTokenFactory, storeTokenScopesFactory, @@ -75,6 +74,7 @@ const { updateApiTokenFactory } = require('@/modules/core/repositories/tokens') const { getServerInfoFactory } = require('@/modules/core/repositories/server') +const { getEventBus } = require('@/modules/shared/services/eventBus') const db = knex const getApp = getAppFactory({ db: knex }) @@ -141,7 +141,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const validateToken = validateTokenFactory({ revokeUserTokenById: revokeUserTokenByIdFactory({ db }), diff --git a/packages/server/modules/auth/tests/auth.spec.js b/packages/server/modules/auth/tests/auth.spec.js index b97d53c5fb..45f75cd951 100644 --- a/packages/server/modules/auth/tests/auth.spec.js +++ b/packages/server/modules/auth/tests/auth.spec.js @@ -37,7 +37,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -66,7 +65,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory, updateServerInfoFactory @@ -102,7 +100,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -131,7 +129,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const getUserByEmail = legacyGetUserByEmailFactory({ db }) const updateServerInfo = updateServerInfoFactory({ db }) diff --git a/packages/server/modules/blobstorage/tests/blobstorage.graph.spec.js b/packages/server/modules/blobstorage/tests/blobstorage.graph.spec.js index a612599375..dc5469f9ba 100644 --- a/packages/server/modules/blobstorage/tests/blobstorage.graph.spec.js +++ b/packages/server/modules/blobstorage/tests/blobstorage.graph.spec.js @@ -34,7 +34,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -62,7 +61,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const getServerInfo = getServerInfoFactory({ db }) @@ -93,7 +91,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -122,7 +120,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('Blobs graphql @blobstorage', () => { diff --git a/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.ts b/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.ts index bb512e3570..578e17188d 100644 --- a/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.ts +++ b/packages/server/modules/blobstorage/tests/blobstorage.integration.spec.ts @@ -27,7 +27,6 @@ import { sendEmail } from '@/modules/emails/services/sending' import { createUserFactory } from '@/modules/core/services/users/management' import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { createTokenFactory } from '@/modules/core/services/tokens' import { storeApiTokenFactory, @@ -42,6 +41,7 @@ import { faker } from '@faker-js/faker' import { BasicTestUser } from '@/test/authHelper' import cryptoRandomString from 'crypto-random-string' import type { BlobStorageItem } from '@/modules/blobstorage/domain/types' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) @@ -70,7 +70,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createRandomUser = async (): Promise => { diff --git a/packages/server/modules/cli/commands/download/project.ts b/packages/server/modules/cli/commands/download/project.ts index 1c7f386b79..069f13c73b 100644 --- a/packages/server/modules/cli/commands/download/project.ts +++ b/packages/server/modules/cli/commands/download/project.ts @@ -59,7 +59,6 @@ import { import { getBlobsFactory } from '@/modules/blobstorage/repositories' import { validateInputAttachmentsFactory } from '@/modules/comments/services/commentTextService' import { VersionsEmitter } from '@/modules/core/events/versionsEmitter' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { saveActivityFactory } from '@/modules/activitystream/repositories' import { publish } from '@/modules/shared/utils/subscriptions' import { addCommitCreatedActivityFactory } from '@/modules/activitystream/services/commitActivity' @@ -78,6 +77,7 @@ import { storeProjectRoleFactory } from '@/modules/core/repositories/projects' import { storeModelFactory } from '@/modules/core/repositories/models' +import { getEventBus } from '@/modules/shared/services/eventBus' const command: CommandModule< unknown, @@ -220,7 +220,7 @@ const command: CommandModule< storeModel: storeModelFactory({ db: projectDb }), // THIS MUST GO TO THE MAIN DB storeProjectRole: storeProjectRoleFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) const createObject = createObjectFactory({ diff --git a/packages/server/modules/comments/tests/comments.graph.spec.js b/packages/server/modules/comments/tests/comments.graph.spec.js index 25322858d4..d777048dd5 100644 --- a/packages/server/modules/comments/tests/comments.graph.spec.js +++ b/packages/server/modules/comments/tests/comments.graph.spec.js @@ -82,7 +82,6 @@ const { buildCoreInviteEmailContentsFactory } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { saveActivityFactory } = require('@/modules/activitystream/repositories') const { publish } = require('@/modules/shared/utils/subscriptions') const { @@ -115,7 +114,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const { createObjectFactory } = require('@/modules/core/services/objects/management') @@ -186,7 +184,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -220,7 +218,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createObject = createObjectFactory({ storeSingleObjectIfNotFoundFactory: storeSingleObjectIfNotFoundFactory({ db }), diff --git a/packages/server/modules/comments/tests/comments.spec.js b/packages/server/modules/comments/tests/comments.spec.js index a88a4974a3..d2e63fa187 100644 --- a/packages/server/modules/comments/tests/comments.spec.js +++ b/packages/server/modules/comments/tests/comments.spec.js @@ -101,7 +101,6 @@ const { buildCoreInviteEmailContentsFactory } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { saveActivityFactory } = require('@/modules/activitystream/repositories') const { publish } = require('@/modules/shared/utils/subscriptions') const { @@ -134,7 +133,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const { createObjectFactory } = require('@/modules/core/services/objects/management') @@ -234,7 +232,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -263,7 +261,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createObject = createObjectFactory({ storeSingleObjectIfNotFoundFactory: storeSingleObjectIfNotFoundFactory({ db }), diff --git a/packages/server/modules/core/domain/branches/events.ts b/packages/server/modules/core/domain/branches/events.ts new file mode 100644 index 0000000000..a76bc7cda2 --- /dev/null +++ b/packages/server/modules/core/domain/branches/events.ts @@ -0,0 +1,11 @@ +import { Model } from '@/modules/core/domain/branches/types' + +export const modelEventsNamespace = 'models' as const + +export const ModelEvents = { + Deleted: `${modelEventsNamespace}.deleted` +} as const + +export type ModelEventsPayloads = { + [ModelEvents.Deleted]: { projectId: string; modelId: string; model: Model } +} diff --git a/packages/server/modules/core/domain/projects/events.ts b/packages/server/modules/core/domain/projects/events.ts new file mode 100644 index 0000000000..129c2b132c --- /dev/null +++ b/packages/server/modules/core/domain/projects/events.ts @@ -0,0 +1,11 @@ +import { Project } from '@/modules/core/domain/streams/types' + +export const projectEventsNamespace = 'projects' as const + +export const ProjectEvents = { + Created: `${projectEventsNamespace}.created` +} as const + +export type ProjectEventsPayloads = { + [ProjectEvents.Created]: { project: Project; ownerId: string } +} diff --git a/packages/server/modules/core/domain/users/events.ts b/packages/server/modules/core/domain/users/events.ts new file mode 100644 index 0000000000..3d0d1757be --- /dev/null +++ b/packages/server/modules/core/domain/users/events.ts @@ -0,0 +1,18 @@ +import { User, UserSignUpContext } from '@/modules/core/domain/users/types' +import { Optional } from '@speckle/shared' + +export const userEventsNamespace = 'users' as const + +export const UserEvents = { + Created: `${userEventsNamespace}.created` +} as const + +export type UserEventsPayloads = { + [UserEvents.Created]: { + user: User + /** + * Should be set in all real non-simulated sign up sessions + */ + signUpCtx: Optional + } +} diff --git a/packages/server/modules/core/events/modelsEmitter.ts b/packages/server/modules/core/events/modelsEmitter.ts deleted file mode 100644 index 13d2bfdb5f..0000000000 --- a/packages/server/modules/core/events/modelsEmitter.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { BranchRecord } from '@/modules/core/helpers/types' -import { initializeModuleEventEmitter } from '@/modules/shared/services/moduleEventEmitterSetup' - -export enum ModelEvents { - Deleted = 'created' -} - -export type ModelEventsPayloads = { - [ModelEvents.Deleted]: { projectId: string; modelId: string; model: BranchRecord } -} - -const { emit, listen } = initializeModuleEventEmitter({ - moduleName: 'core', - namespace: 'users' -}) - -export const ModelsEmitter = { emit, listen, events: ModelEvents } -export type ModelsEventsEmitter = (typeof ModelsEmitter)['emit'] diff --git a/packages/server/modules/core/events/projectsEmitter.ts b/packages/server/modules/core/events/projectsEmitter.ts deleted file mode 100644 index 01e21cf2ec..0000000000 --- a/packages/server/modules/core/events/projectsEmitter.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { StreamRecord } from '@/modules/core/helpers/types' -import { initializeModuleEventEmitter } from '@/modules/shared/services/moduleEventEmitterSetup' - -export const ProjectEvents = { - Created: 'created' -} as const - -export type ProjectEvents = (typeof ProjectEvents)[keyof typeof ProjectEvents] - -export type ProjectEventsPayloads = { - [ProjectEvents.Created]: { project: StreamRecord; ownerId: string } -} - -const { emit, listen } = initializeModuleEventEmitter({ - moduleName: 'core', - namespace: 'projects' -}) - -export const ProjectsEmitter = { emit, listen, events: ProjectEvents } -export type ProjectsEventsEmitter = (typeof ProjectsEmitter)['emit'] -export type ProjectsEventsListener = (typeof ProjectsEmitter)['listen'] diff --git a/packages/server/modules/core/events/usersEmitter.ts b/packages/server/modules/core/events/usersEmitter.ts deleted file mode 100644 index d3fc7cf56e..0000000000 --- a/packages/server/modules/core/events/usersEmitter.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { UserSignUpContext } from '@/modules/core/domain/users/types' -import { UserRecord } from '@/modules/core/helpers/types' -import { initializeModuleEventEmitter } from '@/modules/shared/services/moduleEventEmitterSetup' -import { Optional } from '@speckle/shared' - -export enum UsersEvents { - Created = 'created' -} - -export type UsersEventsPayloads = { - [UsersEvents.Created]: { - user: UserRecord - /** - * Should be set in all real non-simulated sign up sessions - */ - signUpCtx: Optional - } -} - -const { emit, listen } = initializeModuleEventEmitter({ - moduleName: 'core', - namespace: 'users' -}) - -export const UsersEmitter = { emit, listen, events: UsersEvents } -export type UsersEventsEmitter = (typeof UsersEmitter)['emit'] -export type UsersEventsListener = (typeof UsersEmitter)['listen'] diff --git a/packages/server/modules/core/graph/resolvers/branches.ts b/packages/server/modules/core/graph/resolvers/branches.ts index 40eb9de674..1da138c841 100644 --- a/packages/server/modules/core/graph/resolvers/branches.ts +++ b/packages/server/modules/core/graph/resolvers/branches.ts @@ -25,13 +25,13 @@ import { getStreamFactory, markBranchStreamUpdatedFactory } from '@/modules/core/repositories/streams' -import { ModelsEmitter } from '@/modules/core/events/modelsEmitter' import { legacyGetUserFactory } from '@/modules/core/repositories/users' import { Resolvers } from '@/modules/core/graph/generated/graphql' import { getPaginatedStreamBranchesFactory } from '@/modules/core/services/branch/retrieval' import { saveActivityFactory } from '@/modules/activitystream/repositories' import { filteredSubscribe, publish } from '@/modules/shared/utils/subscriptions' import { getProjectDbClient } from '@/modules/multiregion/utils/dbSelector' +import { getEventBus } from '@/modules/shared/services/eventBus' export = { Query: {}, @@ -135,7 +135,7 @@ export = { const deleteBranchAndNotify = deleteBranchAndNotifyFactory({ getStream, getBranchById: getBranchByIdFactory({ db: projectDB }), - modelsEventsEmitter: ModelsEmitter.emit, + emitEvent: getEventBus().emit, markBranchStreamUpdated, addBranchDeletedActivity: addBranchDeletedActivityFactory({ saveActivity: saveActivityFactory({ db }), diff --git a/packages/server/modules/core/graph/resolvers/models.ts b/packages/server/modules/core/graph/resolvers/models.ts index e596405707..0b50815533 100644 --- a/packages/server/modules/core/graph/resolvers/models.ts +++ b/packages/server/modules/core/graph/resolvers/models.ts @@ -59,12 +59,12 @@ import { getStreamFactory, markBranchStreamUpdatedFactory } from '@/modules/core/repositories/streams' -import { ModelsEmitter } from '@/modules/core/events/modelsEmitter' import { saveActivityFactory } from '@/modules/activitystream/repositories' import { getProjectDbClient, getRegisteredRegionClients } from '@/modules/multiregion/utils/dbSelector' +import { getEventBus } from '@/modules/shared/services/eventBus' export = { User: { @@ -350,7 +350,7 @@ export = { const deleteBranchAndNotify = deleteBranchAndNotifyFactory({ getStream, getBranchById: getBranchByIdFactory({ db: projectDB }), - modelsEventsEmitter: ModelsEmitter.emit, + emitEvent: getEventBus().emit, markBranchStreamUpdated, addBranchDeletedActivity: addBranchDeletedActivityFactory({ saveActivity: saveActivityFactory({ db }), diff --git a/packages/server/modules/core/graph/resolvers/projects.ts b/packages/server/modules/core/graph/resolvers/projects.ts index fc6bc83ae4..91aed50de6 100644 --- a/packages/server/modules/core/graph/resolvers/projects.ts +++ b/packages/server/modules/core/graph/resolvers/projects.ts @@ -16,7 +16,6 @@ import { } from '@/modules/comments/repositories/comments' import { RateLimitError } from '@/modules/core/errors/ratelimit' import { StreamNotFoundError } from '@/modules/core/errors/stream' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { ProjectVisibility, Resolvers, @@ -119,7 +118,7 @@ const createStreamReturnRecord = createStreamReturnRecordFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) const validateStreamAccess = validateStreamAccessFactory({ authorizeResolver }) const isStreamCollaborator = isStreamCollaboratorFactory({ diff --git a/packages/server/modules/core/graph/resolvers/streams.ts b/packages/server/modules/core/graph/resolvers/streams.ts index 06110ea80c..0e3ab7eb8b 100644 --- a/packages/server/modules/core/graph/resolvers/streams.ts +++ b/packages/server/modules/core/graph/resolvers/streams.ts @@ -71,7 +71,6 @@ import { addStreamUpdatedActivityFactory } from '@/modules/activitystream/services/streamActivity' import { saveActivityFactory } from '@/modules/activitystream/repositories' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { addOrUpdateStreamCollaboratorFactory, isStreamCollaboratorFactory, @@ -119,7 +118,7 @@ const createStreamReturnRecord = createStreamReturnRecordFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) const deleteStreamAndNotify = deleteStreamAndNotifyFactory({ deleteStream: deleteStreamFactory({ db }), diff --git a/packages/server/modules/core/services/branch/management.ts b/packages/server/modules/core/services/branch/management.ts index c2822ec539..3b7aa76415 100644 --- a/packages/server/modules/core/services/branch/management.ts +++ b/packages/server/modules/core/services/branch/management.ts @@ -15,7 +15,6 @@ import { import { BranchRecord } from '@/modules/core/helpers/types' import { has } from 'lodash' import { isBranchDeleteInput, isBranchUpdateInput } from '@/modules/core/helpers/branch' -import { ModelsEmitter, ModelsEventsEmitter } from '@/modules/core/events/modelsEmitter' import { CreateBranchAndNotify, DeleteBranchAndNotify, @@ -35,6 +34,8 @@ import { AddBranchDeletedActivity, AddBranchUpdatedActivity } from '@/modules/activitystream/domain/operations' +import { EventBusEmit } from '@/modules/shared/services/eventBus' +import { ModelEvents } from '@/modules/core/domain/branches/events' const isBranchCreateInput = ( i: BranchCreateInput | CreateModelInput @@ -127,7 +128,7 @@ export const deleteBranchAndNotifyFactory = (deps: { getStream: GetStream getBranchById: GetBranchById - modelsEventsEmitter: ModelsEventsEmitter + emitEvent: EventBusEmit markBranchStreamUpdated: MarkBranchStreamUpdated addBranchDeletedActivity: AddBranchDeletedActivity deleteBranchById: DeleteBranchById @@ -172,10 +173,13 @@ export const deleteBranchAndNotifyFactory = branchName: existingBranch.name }), deps.markBranchStreamUpdated(input.id), - deps.modelsEventsEmitter(ModelsEmitter.events.Deleted, { - modelId: existingBranch.id, - model: existingBranch, - projectId: streamId + deps.emitEvent({ + eventName: ModelEvents.Deleted, + payload: { + modelId: existingBranch.id, + model: existingBranch, + projectId: streamId + } }) ]) } diff --git a/packages/server/modules/core/services/projects.ts b/packages/server/modules/core/services/projects.ts index f5f12abea9..cd404cf418 100644 --- a/packages/server/modules/core/services/projects.ts +++ b/packages/server/modules/core/services/projects.ts @@ -1,3 +1,4 @@ +import { ProjectEvents } from '@/modules/core/domain/projects/events' import { generateProjectName } from '@/modules/core/domain/projects/logic' import { CreateProject, @@ -11,10 +12,7 @@ import { import { Project } from '@/modules/core/domain/streams/types' import { RegionalProjectCreationError } from '@/modules/core/errors/projects' import { StreamNotFoundError } from '@/modules/core/errors/stream' -import { - ProjectEvents, - ProjectsEventsEmitter -} from '@/modules/core/events/projectsEmitter' +import { EventBusEmit } from '@/modules/shared/services/eventBus' import { retry } from '@lifeomic/attempt' import { Roles } from '@speckle/shared' import cryptoRandomString from 'crypto-random-string' @@ -26,13 +24,13 @@ export const createNewProjectFactory = deleteProject, storeProjectRole, storeModel, - projectsEventsEmitter + emitEvent }: { storeProject: StoreProject getProject: GetProject deleteProject: DeleteProject storeProjectRole: StoreProjectRole - projectsEventsEmitter: ProjectsEventsEmitter + emitEvent: EventBusEmit storeModel: StoreModel }): CreateProject => async ({ description, name, regionKey, visibility, workspaceId, ownerId }) => { @@ -81,6 +79,6 @@ export const createNewProjectFactory = projectId, authorId: ownerId }) - await projectsEventsEmitter(ProjectEvents.Created, { project, ownerId }) + await emitEvent({ eventName: ProjectEvents.Created, payload: { project, ownerId } }) return project } diff --git a/packages/server/modules/core/services/streams/management.ts b/packages/server/modules/core/services/streams/management.ts index 93ca7376a5..ec92290000 100644 --- a/packages/server/modules/core/services/streams/management.ts +++ b/packages/server/modules/core/services/streams/management.ts @@ -20,10 +20,6 @@ import { TokenResourceIdentifier, TokenResourceIdentifierType } from '@/modules/core/domain/tokens/types' -import { - ProjectEvents, - ProjectsEventsEmitter -} from '@/modules/core/events/projectsEmitter' import { inviteUsersToProjectFactory } from '@/modules/serverinvites/services/projectInviteManagement' import { ProjectInviteResourceType } from '@/modules/serverinvites/domain/constants' import { @@ -50,13 +46,15 @@ import { AddStreamUpdatedActivity } from '@/modules/activitystream/domain/operations' import { LogicError } from '@/modules/shared/errors' +import { EventBusEmit } from '@/modules/shared/services/eventBus' +import { ProjectEvents } from '@/modules/core/domain/projects/events' export const createStreamReturnRecordFactory = (deps: { createStream: StoreStream createBranch: StoreBranch inviteUsersToProject: ReturnType - projectsEventsEmitter: ProjectsEventsEmitter + emitEvent: EventBusEmit }): CreateStream => async (params): Promise => { const { ownerId, ownerResourceAccessRules } = params @@ -93,9 +91,12 @@ export const createStreamReturnRecordFactory = ) } - await deps.projectsEventsEmitter(ProjectEvents.Created, { - project: stream, - ownerId + await deps.emitEvent({ + eventName: ProjectEvents.Created, + payload: { + project: stream, + ownerId + } }) return stream diff --git a/packages/server/modules/core/services/users/management.ts b/packages/server/modules/core/services/users/management.ts index 7b34aeffbd..14ba67ec28 100644 --- a/packages/server/modules/core/services/users/management.ts +++ b/packages/server/modules/core/services/users/management.ts @@ -36,7 +36,6 @@ import { FindPrimaryEmailForUser, ValidateAndCreateUserEmail } from '@/modules/core/domain/userEmails/operations' -import { UsersEvents, UsersEventsEmitter } from '@/modules/core/events/usersEmitter' import { DeleteStreamRecord, GetUserDeletableStreams @@ -44,6 +43,8 @@ import { import { Logger } from '@/logging/logging' import { DeleteAllUserInvites } from '@/modules/serverinvites/domain/operations' import { GetServerInfo } from '@/modules/core/domain/server/operations' +import { EventBusEmit } from '@/modules/shared/services/eventBus' +import { UserEvents } from '@/modules/core/domain/users/events' export const MINIMUM_PASSWORD_LENGTH = 8 @@ -138,7 +139,7 @@ export const createUserFactory = countAdminUsers: CountAdminUsers storeUserAcl: StoreUserAcl validateAndCreateUserEmail: ValidateAndCreateUserEmail - usersEventsEmitter: UsersEventsEmitter + emitEvent: EventBusEmit }): CreateValidatedUser => async (user, options = undefined) => { // ONLY ALLOW SKIPPING WHEN CREATING USERS FOR TESTS, IT'S UNSAFE OTHERWISE @@ -223,7 +224,10 @@ export const createUserFactory = } }) - await deps.usersEventsEmitter(UsersEvents.Created, { user: newUser, signUpCtx }) + await deps.emitEvent({ + eventName: UserEvents.Created, + payload: { user: newUser, signUpCtx } + }) return newUser.id } diff --git a/packages/server/modules/core/tests/branches.spec.js b/packages/server/modules/core/tests/branches.spec.ts similarity index 65% rename from packages/server/modules/core/tests/branches.spec.js rename to packages/server/modules/core/tests/branches.spec.ts index fb86a67d2f..b07e318265 100644 --- a/packages/server/modules/core/tests/branches.spec.js +++ b/packages/server/modules/core/tests/branches.spec.ts @@ -1,19 +1,19 @@ /* istanbul ignore file */ -const chai = require('chai') -const assert = require('assert') +import chai from 'chai' +import assert from 'assert' -const { beforeEachContext } = require('@/test/hooks') -const { sleep } = require('@/test/helpers') +import { beforeEachContext } from '@/test/hooks' +import { sleep } from '@/test/helpers' const expect = chai.expect -const { knex } = require('@/db/knex') +import { knex } from '@/db/knex' -const { +import { updateBranchAndNotifyFactory, deleteBranchAndNotifyFactory -} = require('@/modules/core/services/branch/management') -const { +} from '@/modules/core/services/branch/management' +import { getBranchByIdFactory, getStreamBranchByNameFactory, createBranchFactory, @@ -22,95 +22,74 @@ const { markCommitBranchUpdatedFactory, getPaginatedStreamBranchesPageFactory, getStreamBranchCountFactory -} = require('@/modules/core/repositories/branches') -const { +} from '@/modules/core/repositories/branches' +import { addBranchUpdatedActivityFactory, addBranchDeletedActivityFactory -} = require('@/modules/activitystream/services/branchActivity') -const { +} from '@/modules/activitystream/services/branchActivity' +import { getStreamFactory, createStreamFactory, markBranchStreamUpdatedFactory, markCommitStreamUpdatedFactory -} = require('@/modules/core/repositories/streams') -const { ModelsEmitter } = require('@/modules/core/events/modelsEmitter') -const { +} from '@/modules/core/repositories/streams' +import { createCommitByBranchIdFactory, createCommitByBranchNameFactory -} = require('@/modules/core/services/commit/management') -const { +} from '@/modules/core/services/commit/management' +import { createCommitFactory, insertStreamCommitsFactory, insertBranchCommitsFactory -} = require('@/modules/core/repositories/commits') -const { VersionsEmitter } = require('@/modules/core/events/versionsEmitter') -const { +} from '@/modules/core/repositories/commits' +import { VersionsEmitter } from '@/modules/core/events/versionsEmitter' +import { getObjectFactory, storeSingleObjectIfNotFoundFactory, storeClosuresIfNotFoundFactory -} = require('@/modules/core/repositories/objects') -const { +} from '@/modules/core/repositories/objects' +import { legacyCreateStreamFactory, createStreamReturnRecordFactory -} = require('@/modules/core/services/streams/management') -const { - inviteUsersToProjectFactory -} = require('@/modules/serverinvites/services/projectInviteManagement') -const { - createAndSendInviteFactory -} = require('@/modules/serverinvites/services/creation') -const { +} from '@/modules/core/services/streams/management' +import { inviteUsersToProjectFactory } from '@/modules/serverinvites/services/projectInviteManagement' +import { createAndSendInviteFactory } from '@/modules/serverinvites/services/creation' +import { findUserByTargetFactory, insertInviteAndDeleteOldFactory, deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory -} = require('@/modules/serverinvites/repositories/serverInvites') -const { - collectAndValidateCoreTargetsFactory -} = require('@/modules/serverinvites/services/coreResourceCollection') -const { - buildCoreInviteEmailContentsFactory -} = require('@/modules/serverinvites/services/coreEmailContents') -const { getEventBus } = require('@/modules/shared/services/eventBus') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') -const { saveActivityFactory } = require('@/modules/activitystream/repositories') -const { publish } = require('@/modules/shared/utils/subscriptions') -const { - addCommitCreatedActivityFactory -} = require('@/modules/activitystream/services/commitActivity') -const { +} from '@/modules/serverinvites/repositories/serverInvites' +import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/services/coreResourceCollection' +import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' +import { getEventBus } from '@/modules/shared/services/eventBus' +import { saveActivityFactory } from '@/modules/activitystream/repositories' +import { publish } from '@/modules/shared/utils/subscriptions' +import { addCommitCreatedActivityFactory } from '@/modules/activitystream/services/commitActivity' +import { getUsersFactory, getUserFactory, storeUserFactory, countAdminUsersFactory, storeUserAclFactory -} = require('@/modules/core/repositories/users') -const { +} from '@/modules/core/repositories/users' +import { findEmailFactory, createUserEmailFactory, ensureNoPrimaryEmailForUserFactory -} = require('@/modules/core/repositories/userEmails') -const { - requestNewEmailVerificationFactory -} = require('@/modules/emails/services/verification/request') -const { - deleteOldAndInsertNewVerificationFactory -} = require('@/modules/emails/repositories') -const { renderEmail } = require('@/modules/emails/services/emailRendering') -const { sendEmail } = require('@/modules/emails/services/sending') -const { createUserFactory } = require('@/modules/core/services/users/management') -const { - validateAndCreateUserEmailFactory -} = require('@/modules/core/services/userEmails') -const { - finalizeInvitedServerRegistrationFactory -} = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') -const { getServerInfoFactory } = require('@/modules/core/repositories/server') -const { - getPaginatedStreamBranchesFactory -} = require('@/modules/core/services/branch/retrieval') -const { createObjectFactory } = require('@/modules/core/services/objects/management') +} from '@/modules/core/repositories/userEmails' +import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' +import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' +import { createUserFactory } from '@/modules/core/services/users/management' +import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' +import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' +import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getPaginatedStreamBranchesFactory } from '@/modules/core/services/branch/retrieval' +import { createObjectFactory } from '@/modules/core/services/objects/management' +import { ensureError } from '@speckle/shared' +import { ModelEvents } from '@/modules/core/domain/branches/events' const db = knex const Commits = () => knex('commits') @@ -134,7 +113,7 @@ const updateBranchAndNotify = updateBranchAndNotifyFactory({ const deleteBranchAndNotify = deleteBranchAndNotifyFactory({ getStream, getBranchById: getBranchByIdFactory({ db: knex }), - modelsEventsEmitter: ModelsEmitter.emit, + emitEvent: getEventBus().emit, markBranchStreamUpdated, addBranchDeletedActivity: addBranchDeletedActivityFactory({ saveActivity: saveActivityFactory({ db }), @@ -190,7 +169,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -219,7 +198,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const getBranchesByStreamId = getPaginatedStreamBranchesFactory({ getPaginatedStreamBranchesPage: getPaginatedStreamBranchesPageFactory({ db }), @@ -234,19 +213,24 @@ describe('Branches @core-branches', () => { const user = { name: 'Dimitrie Stefanescu', email: 'didimitrie4342@gmail.com', - password: 'sn3aky-1337-b1m' + password: 'sn3aky-1337-b1m', + id: '' } const stream = { name: 'Test Stream References', - description: 'Whatever goes in here usually...' + description: 'Whatever goes in here usually...', + id: '' } const testObject = { foo: 'bar', - baz: 'qux' + baz: 'qux', + id: '' } + let quitters: (() => void)[] = [] + before(async () => { await beforeEachContext() @@ -255,7 +239,12 @@ describe('Branches @core-branches', () => { testObject.id = await createObject({ streamId: stream.id, object: testObject }) }) - const branch = { name: 'dim/dev' } + afterEach(() => { + quitters.forEach((quit) => quit()) + quitters = [] + }) + + const branch = { name: 'dim/dev', id: '', description: null } it('Should create a branch', async () => { branch.id = ( @@ -271,26 +260,43 @@ describe('Branches @core-branches', () => { it('Should not allow duplicate branch names', async () => { try { - await createBranch({ name: 'main', streamId: stream.id, authorId: user.id }) + await createBranch({ + name: 'main', + streamId: stream.id, + authorId: user.id, + description: null + }) assert.fail('Duplicate branches should not be allowed.') } catch (err) { - expect(err.message).to.contain('duplicate key value violates unique constraint') + expect(ensureError(err).message).to.contain( + 'duplicate key value violates unique constraint' + ) } }) it('Should not allow branch names starting with # or /, or branches that have "//" in their name', async () => { try { - await createBranch({ name: '/pasta', streamId: stream.id, authorId: user.id }) + await createBranch({ + name: '/pasta', + streamId: stream.id, + authorId: user.id, + description: null + }) assert.fail('Illegal branch name passed through.') } catch (err) { - expect(err.message).to.contain('Branch names cannot start with') + expect(ensureError(err).message).to.contain('Branch names cannot start with') } try { - await createBranch({ name: '#rice', streamId: stream.id, authorId: user.id }) + await createBranch({ + name: '#rice', + streamId: stream.id, + authorId: user.id, + description: null + }) assert.fail('Illegal branch name passed through.') } catch (err) { - expect(err.message).to.contain('Branch names cannot start with') + expect(ensureError(err).message).to.contain('Branch names cannot start with') } try { @@ -304,7 +310,7 @@ describe('Branches @core-branches', () => { ) assert.fail('Illegal branch name passed through in update operation.') } catch (err) { - expect(err.message).to.contain('Branch names cannot start with') + expect(ensureError(err).message).to.contain('Branch names cannot start with') } try { @@ -318,18 +324,19 @@ describe('Branches @core-branches', () => { ) assert.fail('Illegal branch name passed through in update operation.') } catch (err) { - expect(err.message).to.contain('Branch names cannot start with') + expect(ensureError(err).message).to.contain('Branch names cannot start with') } try { await createBranch({ name: 'pasta//rice', streamId: stream.id, - authorId: user.id + authorId: user.id, + description: null }) assert.fail('Illegal branch name passed through.') } catch (err) { - expect(err.message).to.contain('Branch names cannot start with') + expect(ensureError(err).message).to.contain('Branch names cannot start with') } }) @@ -338,18 +345,19 @@ describe('Branches @core-branches', () => { await createBranch({ name: 'CaseSensitive', streamId: stream.id, - authorId: user.id + authorId: user.id, + description: null }) ).id const b = await getStreamBranchByName(stream.id, 'casesensitive') - expect(b.name).to.equal('casesensitive') + expect(b!.name).to.equal('casesensitive') const bb = await getStreamBranchByName(stream.id, 'CaseSensitive') - expect(bb.name).to.equal('casesensitive') + expect(bb!.name).to.equal('casesensitive') const bbb = await getStreamBranchByName(stream.id, 'CASESENSITIVE') - expect(bbb.name).to.equal('casesensitive') + expect(bbb!.name).to.equal('casesensitive') // cleanup await deleteBranchAndNotify({ id, streamId: stream.id }, user.id) @@ -357,8 +365,8 @@ describe('Branches @core-branches', () => { it('Should get a branch', async () => { const myBranch = await getBranchById(branch.id) - expect(myBranch.authorId).to.equal(user.id) - expect(myBranch.streamId).to.equal(stream.id) + expect(myBranch!.authorId).to.equal(user.id) + expect(myBranch!.streamId).to.equal(stream.id) }) it('Should update a branch', async () => { @@ -372,18 +380,29 @@ describe('Branches @core-branches', () => { ) const b1 = await getBranchById(branch.id) - expect(b1.description).to.equal('lorem ipsum') + expect(b1!.description).to.equal('lorem ipsum') }) it('Should get all stream branches', async () => { - await createBranch({ name: 'main-faster', streamId: stream.id, authorId: user.id }) - await sleep(250) - await createBranch({ name: 'main-blaster', streamId: stream.id, authorId: user.id }) - await sleep(250) + await createBranch({ + name: 'main-faster', + streamId: stream.id, + authorId: user.id, + description: null + }) + await sleep(1) + await createBranch({ + name: 'main-blaster', + streamId: stream.id, + authorId: user.id, + description: null + }) + await sleep(1) await createBranch({ name: 'blaster-farter', streamId: stream.id, - authorId: user.id + authorId: user.id, + description: null }) const { items, cursor, totalCount } = await getBranchesByStreamId(stream.id) @@ -393,9 +412,19 @@ describe('Branches @core-branches', () => { }) it('Should delete a branch', async () => { + let deleteEventFired = false + quitters.push( + getEventBus().listen(ModelEvents.Deleted, async ({ payload }) => { + if (payload.model.id === branch.id) { + deleteEventFired = true + } + }) + ) + await deleteBranchAndNotify({ id: branch.id, streamId: stream.id }, user.id) const { items } = await getBranchesByStreamId(stream.id) expect(items).to.have.lengthOf(4) + expect(deleteEventFired).to.be.true }) it('Deleting a branch should delete the commit', async () => { @@ -405,7 +434,8 @@ describe('Branches @core-branches', () => { await createBranch({ name: branchName, streamId: stream.id, - authorId: user.id + authorId: user.id, + description: null }) ).id @@ -426,7 +456,7 @@ describe('Branches @core-branches', () => { it('Should NOT delete the main branch', async () => { const b = await getStreamBranchByName(stream.id, 'main') try { - await deleteBranchAndNotify({ id: b.id, streamId: stream.id }, user.id) + await deleteBranchAndNotify({ id: b!.id, streamId: stream.id }, user.id) assert.fail() } catch { // pass @@ -439,25 +469,4 @@ describe('Branches @core-branches', () => { expect(items[0].name).to.equal('main') expect(items[1].createdAt < items[2].createdAt).to.equal(true) }) - - // NOTE: pagination broken currently, we need to do a global fix - // pausing this for now to be able to put out other fixes - // it('Should paginate branches correctly', async () => { - // const { items: firstBatch, cursor } = await getBranchesByStreamId({ - // streamId: stream.id, - // limit: 2 - // }) - // const test = JSON.stringify(cursor) - // console.log(test) - // expect(firstBatch.length).to.equal(2) - // const { items: secondBatch } = await getBranchesByStreamId({ - // streamId: stream.id, - // cursor, - // limit: 2 - // }) - // expect(secondBatch.length).to.equal(2) - // console.log(secondBatch[0].createdAt) - // console.log(firstBatch[1].createdAt) - // expect(secondBatch[0].createdAt > firstBatch[1].createdAt).to.equal(true) - // }) }) diff --git a/packages/server/modules/core/tests/commits.spec.js b/packages/server/modules/core/tests/commits.spec.js index ed55ccd3a8..26a5d03e11 100644 --- a/packages/server/modules/core/tests/commits.spec.js +++ b/packages/server/modules/core/tests/commits.spec.js @@ -75,7 +75,6 @@ const { buildCoreInviteEmailContentsFactory } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { saveActivityFactory } = require('@/modules/activitystream/repositories') const { publish } = require('@/modules/shared/utils/subscriptions') const { @@ -105,7 +104,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const { getBranchCommitsTotalCountByNameFactory, @@ -206,7 +204,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -235,7 +233,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const getCommitsByUserId = legacyGetPaginatedUserCommitsPage({ db }) const getCommitsByStreamId = legacyGetPaginatedStreamCommitsPageFactory({ db }) diff --git a/packages/server/modules/core/tests/favoriteStreams.spec.js b/packages/server/modules/core/tests/favoriteStreams.spec.js index eb3ff059ec..f649620425 100644 --- a/packages/server/modules/core/tests/favoriteStreams.spec.js +++ b/packages/server/modules/core/tests/favoriteStreams.spec.js @@ -40,7 +40,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -68,7 +67,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const getServerInfo = getServerInfoFactory({ db }) @@ -99,7 +97,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -128,7 +126,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) /** diff --git a/packages/server/modules/core/tests/generic.spec.js b/packages/server/modules/core/tests/generic.spec.js index ee35707e3e..f54a2d6933 100644 --- a/packages/server/modules/core/tests/generic.spec.js +++ b/packages/server/modules/core/tests/generic.spec.js @@ -45,7 +45,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -73,7 +72,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const getServerInfo = getServerInfoFactory({ db }) @@ -104,7 +102,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -133,7 +131,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('Generic AuthN & AuthZ controller tests', () => { diff --git a/packages/server/modules/core/tests/graph.spec.js b/packages/server/modules/core/tests/graph.spec.js index 633bb679cd..cbf61264f3 100644 --- a/packages/server/modules/core/tests/graph.spec.js +++ b/packages/server/modules/core/tests/graph.spec.js @@ -63,7 +63,6 @@ const { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } = require('@/modules/serverinvites/repositories/serverInvites') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { createPersonalAccessTokenFactory } = require('@/modules/core/services/tokens') const { storeApiTokenFactory, @@ -72,6 +71,7 @@ const { storePersonalApiTokenFactory } = require('@/modules/core/repositories/tokens') const { getServerInfoFactory } = require('@/modules/core/repositories/server') +const { getEventBus } = require('@/modules/shared/services/eventBus') const getUser = getUserFactory({ db }) const getStream = getStreamFactory({ db }) @@ -131,7 +131,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ diff --git a/packages/server/modules/core/tests/integration/commits.graph.spec.ts b/packages/server/modules/core/tests/integration/commits.graph.spec.ts index 1231a0a797..92c43edf96 100644 --- a/packages/server/modules/core/tests/integration/commits.graph.spec.ts +++ b/packages/server/modules/core/tests/integration/commits.graph.spec.ts @@ -33,11 +33,11 @@ import { storeUserFactory } from '@/modules/core/repositories/users' import { createUserFactory } from '@/modules/core/services/users/management' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' import { WorkspaceReadOnlyError } from '@/modules/gatekeeper/errors/billing' import gql from 'graphql-tag' import { getFeatureFlags } from '@/modules/shared/helpers/envHelper' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -69,7 +69,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const { FF_BILLING_INTEGRATION_ENABLED } = getFeatureFlags() diff --git a/packages/server/modules/core/tests/integration/createUser.spec.ts b/packages/server/modules/core/tests/integration/createUser.spec.ts index 9633638c28..7b2d7a3746 100644 --- a/packages/server/modules/core/tests/integration/createUser.spec.ts +++ b/packages/server/modules/core/tests/integration/createUser.spec.ts @@ -32,8 +32,9 @@ import { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } from '@/modules/serverinvites/repositories/serverInvites' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' +import { UserEvents } from '@/modules/core/domain/users/events' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -62,15 +63,31 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('Users @core-users', () => { + let quitters: (() => void)[] = [] + beforeEach(async () => { await beforeEachContext() }) + beforeEach(() => { + quitters.forEach((quit) => quit()) + quitters = [] + }) + it('Should create a user', async () => { + let eventFired = false + quitters.push( + getEventBus().listen(UserEvents.Created, async ({ payload }) => { + expect(payload.user).to.be.ok + expect(payload.signUpCtx).to.be.not.ok + eventFired = true + }) + ) + const newUser = { name: 'John Doe', email: createRandomEmail(), @@ -80,6 +97,7 @@ describe('Users @core-users', () => { const actorId = await createUser(newUser) expect(actorId).to.be.a('string') + expect(eventFired).to.be.true }) it('Should store user email lowercase', async () => { diff --git a/packages/server/modules/core/tests/integration/emailVerification.spec.ts b/packages/server/modules/core/tests/integration/emailVerification.spec.ts index 0fdb4379c7..108ed2185d 100644 --- a/packages/server/modules/core/tests/integration/emailVerification.spec.ts +++ b/packages/server/modules/core/tests/integration/emailVerification.spec.ts @@ -29,8 +29,8 @@ import { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } from '@/modules/serverinvites/repositories/serverInvites' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const findEmail = findEmailFactory({ db }) @@ -58,7 +58,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('Verification @user-emails', () => { diff --git a/packages/server/modules/core/tests/integration/findUsers.spec.ts b/packages/server/modules/core/tests/integration/findUsers.spec.ts index 7de1a36537..15800b1a29 100644 --- a/packages/server/modules/core/tests/integration/findUsers.spec.ts +++ b/packages/server/modules/core/tests/integration/findUsers.spec.ts @@ -31,8 +31,8 @@ import { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } from '@/modules/serverinvites/repositories/serverInvites' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUsers = getUsersFactory({ db }) @@ -61,7 +61,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const getUserByEmail = getUserByEmailFactory({ db }) const listUsers = listUsersFactory({ db }) diff --git a/packages/server/modules/core/tests/integration/objects.graph.spec.ts b/packages/server/modules/core/tests/integration/objects.graph.spec.ts index c6140c5100..6c029bc5a7 100644 --- a/packages/server/modules/core/tests/integration/objects.graph.spec.ts +++ b/packages/server/modules/core/tests/integration/objects.graph.spec.ts @@ -34,10 +34,10 @@ import { storeUserFactory } from '@/modules/core/repositories/users' import { createUserFactory } from '@/modules/core/services/users/management' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' import { WorkspaceReadOnlyError } from '@/modules/gatekeeper/errors/billing' import { getFeatureFlags } from '@/modules/shared/helpers/envHelper' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -69,7 +69,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const { FF_BILLING_INTEGRATION_ENABLED } = getFeatureFlags() diff --git a/packages/server/modules/core/tests/integration/objects.rest.spec.ts b/packages/server/modules/core/tests/integration/objects.rest.spec.ts index cf1eea38f4..1174ca82ae 100644 --- a/packages/server/modules/core/tests/integration/objects.rest.spec.ts +++ b/packages/server/modules/core/tests/integration/objects.rest.spec.ts @@ -1,5 +1,4 @@ import { db } from '@/db/knex' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { createRandomEmail, createRandomPassword @@ -42,6 +41,7 @@ import { import { Scopes } from '@speckle/shared' import { expect } from 'chai' import { getFeatureFlags } from '@/modules/shared/helpers/envHelper' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -73,7 +73,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ diff --git a/packages/server/modules/core/tests/integration/subs.graph.spec.ts b/packages/server/modules/core/tests/integration/subs.graph.spec.ts index a31c73a4ee..2ea9839401 100644 --- a/packages/server/modules/core/tests/integration/subs.graph.spec.ts +++ b/packages/server/modules/core/tests/integration/subs.graph.spec.ts @@ -16,7 +16,6 @@ import { addStreamPermissionsRevokedActivityFactory, addStreamUpdatedActivityFactory } from '@/modules/activitystream/services/streamActivity' -import { ModelsEmitter } from '@/modules/core/events/modelsEmitter' import { AllScopes } from '@/modules/core/helpers/mainConstants' import { deleteBranchByIdFactory, @@ -65,6 +64,7 @@ import { import { getProjectDbClient } from '@/modules/multiregion/utils/dbSelector' import { deleteAllResourceInvitesFactory } from '@/modules/serverinvites/repositories/serverInvites' import { authorizeResolver } from '@/modules/shared' +import { getEventBus } from '@/modules/shared/services/eventBus' import { publish } from '@/modules/shared/utils/subscriptions' import { BasicTestWorkspace, @@ -177,7 +177,7 @@ const buildDeleteModel = async (params: { projectId: string }) => { const deleteBranchAndNotify = deleteBranchAndNotifyFactory({ getStream, getBranchById: getBranchByIdFactory({ db: projectDB }), - modelsEventsEmitter: ModelsEmitter.emit, + emitEvent: getEventBus().emit, markBranchStreamUpdated, addBranchDeletedActivity: addBranchDeletedActivityFactory({ saveActivity: saveActivityFactory({ db }), diff --git a/packages/server/modules/core/tests/integration/updateUser.spec.ts b/packages/server/modules/core/tests/integration/updateUser.spec.ts index 0178cd6a13..a2e336f5df 100644 --- a/packages/server/modules/core/tests/integration/updateUser.spec.ts +++ b/packages/server/modules/core/tests/integration/updateUser.spec.ts @@ -32,8 +32,8 @@ import { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } from '@/modules/serverinvites/repositories/serverInvites' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' const userEmailsDB = db(UserEmails.name) @@ -64,7 +64,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const updateUser = updateUserFactory({ db }) diff --git a/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts b/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts index a3a05b8550..b46ab1b779 100644 --- a/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts +++ b/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts @@ -35,8 +35,8 @@ import { storeUserFactory } from '@/modules/core/repositories/users' import { createUserFactory } from '@/modules/core/services/users/management' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -68,7 +68,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('User emails graphql @core', () => { diff --git a/packages/server/modules/core/tests/integration/userEmails.spec.ts b/packages/server/modules/core/tests/integration/userEmails.spec.ts index efca720f75..96dad8cc7d 100644 --- a/packages/server/modules/core/tests/integration/userEmails.spec.ts +++ b/packages/server/modules/core/tests/integration/userEmails.spec.ts @@ -44,8 +44,8 @@ import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repos import { renderEmail } from '@/modules/emails/services/emailRendering' import { sendEmail } from '@/modules/emails/services/sending' import { createUserFactory } from '@/modules/core/services/users/management' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUsers = legacyGetPaginatedUsersFactory({ db }) @@ -80,7 +80,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const getUserByEmail = getUserByEmailFactory({ db }) const legacyGetUserByEmail = legacyGetUserByEmailFactory({ db }) diff --git a/packages/server/modules/core/tests/integration/versions.graph.spec.ts b/packages/server/modules/core/tests/integration/versions.graph.spec.ts index 727422523a..7d6100f3e3 100644 --- a/packages/server/modules/core/tests/integration/versions.graph.spec.ts +++ b/packages/server/modules/core/tests/integration/versions.graph.spec.ts @@ -34,11 +34,11 @@ import { storeUserFactory } from '@/modules/core/repositories/users' import { createUserFactory } from '@/modules/core/services/users/management' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' import { WorkspaceReadOnlyError } from '@/modules/gatekeeper/errors/billing' import { CreateVersionInput } from '@/modules/core/graph/generated/graphql' import { getFeatureFlags } from '@/modules/shared/helpers/envHelper' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -70,7 +70,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const { FF_BILLING_INTEGRATION_ENABLED } = getFeatureFlags() diff --git a/packages/server/modules/core/tests/objects.spec.js b/packages/server/modules/core/tests/objects.spec.js index d51a62ae3a..9298fbb602 100644 --- a/packages/server/modules/core/tests/objects.spec.js +++ b/packages/server/modules/core/tests/objects.spec.js @@ -36,7 +36,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -64,7 +63,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const { createObjectFactory, @@ -133,7 +131,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -162,7 +160,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createObject = createObjectFactory({ storeSingleObjectIfNotFoundFactory: storeSingleObjectIfNotFoundFactory({ db }), diff --git a/packages/server/modules/core/tests/rest.spec.js b/packages/server/modules/core/tests/rest.spec.js index c26897a894..229ca8a495 100644 --- a/packages/server/modules/core/tests/rest.spec.js +++ b/packages/server/modules/core/tests/rest.spec.js @@ -38,7 +38,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -66,7 +65,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { createPersonalAccessTokenFactory } = require('@/modules/core/services/tokens') const { storeTokenScopesFactory, @@ -104,7 +102,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -133,7 +131,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ storeApiToken: storeApiTokenFactory({ db }), diff --git a/packages/server/modules/core/tests/streams.spec.ts b/packages/server/modules/core/tests/streams.spec.ts index a621f792d1..b3fcad1645 100644 --- a/packages/server/modules/core/tests/streams.spec.ts +++ b/packages/server/modules/core/tests/streams.spec.ts @@ -50,7 +50,6 @@ import { } from '@/modules/core/repositories/branches' import { db } from '@/db/knex' import { deleteBranchAndNotifyFactory } from '@/modules/core/services/branch/management' -import { ModelsEmitter } from '@/modules/core/events/modelsEmitter' import { createCommitByBranchIdFactory, createCommitByBranchNameFactory @@ -81,7 +80,6 @@ import { import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/services/coreResourceCollection' import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' import { getEventBus } from '@/modules/shared/services/eventBus' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { addStreamInviteAcceptedActivityFactory, addStreamPermissionsAddedActivityFactory @@ -116,7 +114,7 @@ const createBranch = createBranchFactory({ db }) const deleteBranchAndNotify = deleteBranchAndNotifyFactory({ getStream, getBranchById: getBranchByIdFactory({ db }), - modelsEventsEmitter: ModelsEmitter.emit, + emitEvent: getEventBus().emit, markBranchStreamUpdated, addBranchDeletedActivity: addBranchDeletedActivityFactory({ saveActivity: saveActivityFactory({ db }), @@ -171,7 +169,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const deleteStream = deleteStreamFactory({ db }) @@ -238,6 +236,8 @@ describe('Streams @core-streams', () => { id: '' } + let quitters: (() => void)[] = [] + const userLimitedUserDataSet = [ { display: 'User', limitedUser: false }, { display: 'LimitedUser', limitedUser: true } @@ -253,8 +253,22 @@ describe('Streams @core-streams', () => { ]) }) + afterEach(() => { + quitters.forEach((quit) => quit()) + quitters = [] + }) + describe('Create, Read, Update, Delete Streams', () => { it('Should create a stream', async () => { + let eventFired = false + quitters.push( + getEventBus().listen('projects.created', async ({ payload }) => { + if (payload.project.name === testStream.name) { + eventFired = true + } + }) + ) + const stream1Id = await createStream({ ...testStream, ownerId: userOne.id }) expect(stream1Id).to.not.be.null @@ -263,6 +277,7 @@ describe('Streams @core-streams', () => { ownerId: userOne.id }) expect(stream2Id).to.not.be.null + expect(eventFired).to.be.ok }) it('Should get a stream', async () => { diff --git a/packages/server/modules/core/tests/unit/projects.spec.ts b/packages/server/modules/core/tests/unit/projects.spec.ts index 5097458aa3..0a18a5993c 100644 --- a/packages/server/modules/core/tests/unit/projects.spec.ts +++ b/packages/server/modules/core/tests/unit/projects.spec.ts @@ -1,8 +1,9 @@ +import { ProjectEvents } from '@/modules/core/domain/projects/events' import { Project } from '@/modules/core/domain/streams/types' import { RegionalProjectCreationError } from '@/modules/core/errors/projects' import { StreamNotFoundError } from '@/modules/core/errors/stream' -import { ProjectEvents } from '@/modules/core/events/projectsEmitter' import { createNewProjectFactory } from '@/modules/core/services/projects' +import { isSpecificEventPayload } from '@/modules/shared/services/eventBus' import { expectToThrow } from '@/test/assertionHelper' import { Roles, StreamRoles } from '@speckle/shared' import { expect } from 'chai' @@ -25,7 +26,7 @@ describe('project services @core', () => { }, storeProjectRole: async () => {}, storeModel: async () => {}, - projectsEventsEmitter: async () => [] + emitEvent: async () => {} }) const project = await createNewProject({ ownerId }) @@ -52,7 +53,7 @@ describe('project services @core', () => { }, storeProjectRole: async () => {}, storeModel: async () => {}, - projectsEventsEmitter: async () => [] + emitEvent: async () => {} }) const project = await createNewProject({ ownerId, visibility }) @@ -80,7 +81,7 @@ describe('project services @core', () => { }, storeProjectRole: async () => {}, storeModel: async () => {}, - projectsEventsEmitter: async () => [] + emitEvent: async () => {} }) const project = await createNewProject({ ownerId, visibility }) @@ -106,7 +107,7 @@ describe('project services @core', () => { }, storeProjectRole: async () => {}, storeModel: async () => {}, - projectsEventsEmitter: async () => [] + emitEvent: async () => {} }) const project = await createNewProject({ ownerId, visibility: 'PRIVATE' }) @@ -136,7 +137,7 @@ describe('project services @core', () => { storeModel: async () => { expect.fail() }, - projectsEventsEmitter: async () => { + emitEvent: async () => { expect.fail() } }) @@ -168,7 +169,7 @@ describe('project services @core', () => { storeModel: async () => { expect.fail() }, - projectsEventsEmitter: async () => { + emitEvent: async () => { expect.fail() } }) @@ -223,10 +224,11 @@ describe('project services @core', () => { storeModel: async (args) => { storedModel = args }, - projectsEventsEmitter: async (eventName, payload) => { - emitedEvent = eventName - eventPayload = payload - return [] + emitEvent: async (payload) => { + if (isSpecificEventPayload(payload, ProjectEvents.Created)) { + emitedEvent = payload.eventName + eventPayload = payload.payload + } } }) const project = await createNewProject({ @@ -286,10 +288,11 @@ describe('project services @core', () => { storeModel: async (args) => { storedModel = args }, - projectsEventsEmitter: async (eventName, payload) => { - emitedEvent = eventName - eventPayload = payload - return [] + emitEvent: async (payload) => { + if (isSpecificEventPayload(payload, ProjectEvents.Created)) { + emitedEvent = payload.eventName + eventPayload = payload.payload + } } }) const project = await createNewProject({ ownerId }) diff --git a/packages/server/modules/core/tests/users.spec.js b/packages/server/modules/core/tests/users.spec.ts similarity index 78% rename from packages/server/modules/core/tests/users.spec.js rename to packages/server/modules/core/tests/users.spec.ts index c88a5d17c3..681519147a 100644 --- a/packages/server/modules/core/tests/users.spec.js +++ b/packages/server/modules/core/tests/users.spec.ts @@ -1,81 +1,70 @@ /* istanbul ignore file */ -const expect = require('chai').expect -const assert = require('assert') +import { expect } from 'chai' +import assert from 'assert' -const { +import { createPersonalAccessTokenFactory, validateTokenFactory -} = require('../services/tokens') +} from '@/modules/core/services/tokens' -const { beforeEachContext } = require('@/test/hooks') -const { Scopes, Roles } = require('@speckle/shared') -const { createRandomEmail } = require('../helpers/testHelpers') -const { +import { beforeEachContext } from '@/test/hooks' +import { Scopes, Roles, ensureError } from '@speckle/shared' +import { createRandomEmail } from '@/modules/core/helpers/testHelpers' +import { createBranchFactory, getBranchByIdFactory, markCommitBranchUpdatedFactory, getStreamBranchByNameFactory, getPaginatedStreamBranchesPageFactory, getStreamBranchCountFactory -} = require('@/modules/core/repositories/branches') -const { db } = require('@/db/knex') -const { +} from '@/modules/core/repositories/branches' +import { db } from '@/db/knex' +import { getCommitFactory, createCommitFactory, insertStreamCommitsFactory, insertBranchCommitsFactory, legacyGetPaginatedStreamCommitsPageFactory, getPaginatedBranchCommitsItemsFactory -} = require('@/modules/core/repositories/commits') -const { +} from '@/modules/core/repositories/commits' +import { createCommitByBranchIdFactory, createCommitByBranchNameFactory -} = require('@/modules/core/services/commit/management') -const { +} from '@/modules/core/services/commit/management' +import { getStreamFactory, createStreamFactory, grantStreamPermissionsFactory, markCommitStreamUpdatedFactory, deleteStreamFactory, getUserDeletableStreamsFactory -} = require('@/modules/core/repositories/streams') -const { VersionsEmitter } = require('@/modules/core/events/versionsEmitter') -const { +} from '@/modules/core/repositories/streams' +import { VersionsEmitter } from '@/modules/core/events/versionsEmitter' +import { getObjectFactory, storeSingleObjectIfNotFoundFactory, storeClosuresIfNotFoundFactory -} = require('@/modules/core/repositories/objects') -const { +} from '@/modules/core/repositories/objects' +import { legacyCreateStreamFactory, createStreamReturnRecordFactory -} = require('@/modules/core/services/streams/management') -const { - inviteUsersToProjectFactory -} = require('@/modules/serverinvites/services/projectInviteManagement') -const { - createAndSendInviteFactory -} = require('@/modules/serverinvites/services/creation') -const { +} from '@/modules/core/services/streams/management' +import { inviteUsersToProjectFactory } from '@/modules/serverinvites/services/projectInviteManagement' +import { createAndSendInviteFactory } from '@/modules/serverinvites/services/creation' +import { findUserByTargetFactory, insertInviteAndDeleteOldFactory, deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory, deleteAllUserInvitesFactory -} = require('@/modules/serverinvites/repositories/serverInvites') -const { - collectAndValidateCoreTargetsFactory -} = require('@/modules/serverinvites/services/coreResourceCollection') -const { - buildCoreInviteEmailContentsFactory -} = require('@/modules/serverinvites/services/coreEmailContents') -const { getEventBus } = require('@/modules/shared/services/eventBus') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') -const { saveActivityFactory } = require('@/modules/activitystream/repositories') -const { publish } = require('@/modules/shared/utils/subscriptions') -const { - addCommitCreatedActivityFactory -} = require('@/modules/activitystream/services/commitActivity') -const { +} from '@/modules/serverinvites/repositories/serverInvites' +import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/services/coreResourceCollection' +import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' +import { getEventBus } from '@/modules/shared/services/eventBus' +import { saveActivityFactory } from '@/modules/activitystream/repositories' +import { publish } from '@/modules/shared/utils/subscriptions' +import { addCommitCreatedActivityFactory } from '@/modules/activitystream/services/commitActivity' +import { getUsersFactory, getUserFactory, legacyGetUserFactory, @@ -90,22 +79,18 @@ const { updateUserServerRoleFactory, searchUsersFactory, getUserRoleFactory -} = require('@/modules/core/repositories/users') -const { +} from '@/modules/core/repositories/users' +import { findEmailFactory, createUserEmailFactory, ensureNoPrimaryEmailForUserFactory, findPrimaryEmailForUserFactory -} = require('@/modules/core/repositories/userEmails') -const { - requestNewEmailVerificationFactory -} = require('@/modules/emails/services/verification/request') -const { - deleteOldAndInsertNewVerificationFactory -} = require('@/modules/emails/repositories') -const { renderEmail } = require('@/modules/emails/services/emailRendering') -const { sendEmail } = require('@/modules/emails/services/sending') -const { +} from '@/modules/core/repositories/userEmails' +import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' +import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' +import { createUserFactory, findOrCreateUserFactory, updateUserAndNotifyFactory, @@ -113,19 +98,12 @@ const { validateUserPasswordFactory, deleteUserFactory, changeUserRoleFactory -} = require('@/modules/core/services/users/management') -const { - validateAndCreateUserEmailFactory -} = require('@/modules/core/services/userEmails') -const { - finalizeInvitedServerRegistrationFactory -} = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') -const { - addUserUpdatedActivityFactory -} = require('@/modules/activitystream/services/userActivity') -const { dbLogger } = require('@/logging/logging') -const { +} from '@/modules/core/services/users/management' +import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' +import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' +import { addUserUpdatedActivityFactory } from '@/modules/activitystream/services/userActivity' +import { dbLogger } from '@/logging/logging' +import { storeApiTokenFactory, storeTokenScopesFactory, storeTokenResourceAccessDefinitionsFactory, @@ -136,16 +114,12 @@ const { getTokenScopesByIdFactory, getTokenResourceAccessDefinitionsByIdFactory, updateApiTokenFactory -} = require('@/modules/core/repositories/tokens') -const { getTokenAppInfoFactory } = require('@/modules/auth/repositories/apps') -const { getServerInfoFactory } = require('@/modules/core/repositories/server') -const { - getPaginatedBranchCommitsItemsByNameFactory -} = require('@/modules/core/services/commit/retrieval') -const { - getPaginatedStreamBranchesFactory -} = require('@/modules/core/services/branch/retrieval') -const { createObjectFactory } = require('@/modules/core/services/objects/management') +} from '@/modules/core/repositories/tokens' +import { getTokenAppInfoFactory } from '@/modules/auth/repositories/apps' +import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getPaginatedBranchCommitsItemsByNameFactory } from '@/modules/core/services/commit/retrieval' +import { getPaginatedStreamBranchesFactory } from '@/modules/core/services/branch/retrieval' +import { createObjectFactory } from '@/modules/core/services/objects/management' const getServerInfo = getServerInfoFactory({ db }) const getUser = legacyGetUserFactory({ db }) @@ -201,7 +175,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const grantPermissionsStream = grantStreamPermissionsFactory({ db }) @@ -231,7 +205,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const findOrCreateUser = findOrCreateUserFactory({ createUser, @@ -305,7 +279,8 @@ describe('Actors & Tokens @user-services', () => { const myTestActor = { name: 'Dimitrie Stefanescu', email: 'didimitrie@gmail.com', - password: 'sn3aky-1337-b1m' + password: 'sn3aky-1337-b1m', + id: '' } before(async () => { @@ -323,7 +298,7 @@ describe('Actors & Tokens @user-services', () => { email: 'test@example.org' }) const user = await getUserByEmail({ email: 'TeST@ExamPLE.oRg' }) - expect(user.email).to.equal('test@example.org') + expect(user!.email).to.equal('test@example.org') }) it('Validate password should ignore email casing', async () => { @@ -332,13 +307,14 @@ describe('Actors & Tokens @user-services', () => { ) }) - let ballmerUserId = null + let ballmerUserId: null | string = null it('Find or create should create a user', async () => { - const newUser = {} - newUser.name = 'Steve Ballmer Balls' - newUser.email = 'ballmer@example.test' - newUser.password = 'testthebest' + const newUser: { name: string; email: string; password: string } = { + name: 'Steve Ballmer Balls', + email: 'ballmer@example.test', + password: 'testthebest' + } const { id } = await findOrCreateUser({ user: newUser }) ballmerUserId = id @@ -348,10 +324,11 @@ describe('Actors & Tokens @user-services', () => { }) it('Find or create should NOT create a user', async () => { - const newUser = {} - newUser.name = 'Steve Ballmer Balls' - newUser.email = 'ballmer@example.test' - newUser.password = 'testthebest' + const newUser: { name: string; email: string; password: string } = { + name: 'Steve Ballmer Balls', + email: 'ballmer@example.test', + password: 'testthebest' + } const { id } = await findOrCreateUser({ user: newUser }) expect(id).to.equal(ballmerUserId) @@ -362,21 +339,23 @@ describe('Actors & Tokens @user-services', () => { const soloOwnerStream = { name: 'Test Stream 01', description: 'wonderful test stream', - isPublic: true + isPublic: true, + id: '' } const multiOwnerStream = { name: 'Test Stream 02', description: 'another test stream', - isPublic: true + isPublic: true, + id: '' } soloOwnerStream.id = await createStream({ ...soloOwnerStream, - ownerId: ballmerUserId + ownerId: ballmerUserId! }) multiOwnerStream.id = await createStream({ ...multiOwnerStream, - ownerId: ballmerUserId + ownerId: ballmerUserId! }) await grantPermissionsStream({ @@ -386,16 +365,16 @@ describe('Actors & Tokens @user-services', () => { }) // create a branch for ballmer on the multiowner stream - const branch = { name: 'ballmer/dev' } + const branch = { name: 'ballmer/dev', id: '', description: null } branch.id = ( await createBranch({ ...branch, streamId: multiOwnerStream.id, - authorId: ballmerUserId + authorId: ballmerUserId! }) ).id - const branchSecond = { name: 'steve/jobs' } + const branchSecond = { name: 'steve/jobs', id: '', description: null } branchSecond.id = ( await createBranch({ ...branchSecond, @@ -416,11 +395,11 @@ describe('Actors & Tokens @user-services', () => { message: 'breakfast commit', sourceApplication: 'tests', objectId: objId, - authorId: ballmerUserId + authorId: ballmerUserId! }) ).id - await deleteUser(ballmerUserId) + await deleteUser(ballmerUserId!) if ((await getStream({ streamId: soloOwnerStream.id })) !== undefined) { assert.fail('user stream not deleted') @@ -436,7 +415,8 @@ describe('Actors & Tokens @user-services', () => { const branchCommits = await getCommitsByBranchName({ streamId: multiOwnerStream.id, - branchName: 'ballmer/dev' + branchName: 'ballmer/dev', + limit: 10 }) expect(branchCommits.commits.length).to.equal(1) @@ -448,7 +428,7 @@ describe('Actors & Tokens @user-services', () => { }) expect(commitsByStreamId.commits.length).to.equal(1) - const user = await getUser(ballmerUserId) + const user = await getUser(ballmerUserId!) if (user) assert.fail('user not deleted') }) @@ -457,7 +437,7 @@ describe('Actors & Tokens @user-services', () => { await deleteUser(myTestActor.id) assert.fail('boom') } catch (err) { - expect(err.message).to.equal( + expect(ensureError(err).message).to.equal( 'Cannot remove the last admin role from the server' ) } @@ -475,7 +455,7 @@ describe('Actors & Tokens @user-services', () => { password: 'sn3aky-1337-b1m', email }) - const { users } = await searchUsers('gates', 20, null) + const { users } = await searchUsers('gates', 20) expect(users).to.have.lengthOf(1) expect(users[0].name).to.equal('Bill Gates') }) @@ -495,10 +475,10 @@ describe('Actors & Tokens @user-services', () => { await changeUserRole({ userId: toBeArchivedId, role: Roles.Server.ArchivedUser }) - let { users } = await searchUsers('Library', 20, null) + let { users } = await searchUsers('Library', 20) expect(users).to.have.lengthOf(1) - users = (await searchUsers('Library', 20, null, true)).users + users = (await searchUsers('Library', 20, undefined, true)).users expect(users).to.have.lengthOf(2) }) @@ -526,10 +506,11 @@ describe('Actors & Tokens @user-services', () => { }) it('Should validate user password', async () => { - const actor = {} - actor.password = 'super-test-200' - actor.email = 'e@ma.il' - actor.name = 'Bob Gates' + const actor = { + password: 'super-test-200', + email: 'e@ma.il', + name: 'Bob Gates' + } await createUser(actor) @@ -562,10 +543,10 @@ describe('Actors & Tokens @user-services', () => { }) describe('API Tokens @core-apitokens', () => { - let myFirstToken - let pregeneratedToken - let revokedToken - let expireSoonToken + let myFirstToken: string + let pregeneratedToken: string + let revokedToken: string + let expireSoonToken: string before(async () => { pregeneratedToken = await createPersonalAccessToken(myTestActor.id, 'Whabadub', [ diff --git a/packages/server/modules/core/tests/usersAdmin.spec.js b/packages/server/modules/core/tests/usersAdmin.spec.js index a3155d1857..ee038d628f 100644 --- a/packages/server/modules/core/tests/usersAdmin.spec.js +++ b/packages/server/modules/core/tests/usersAdmin.spec.js @@ -46,13 +46,13 @@ const { updateAllInviteTargetsFactory, deleteAllUserInvitesFactory } = require('@/modules/serverinvites/repositories/serverInvites') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { deleteStreamFactory, getUserDeletableStreamsFactory } = require('@/modules/core/repositories/streams') const { dbLogger } = require('@/logging/logging') const { getServerInfoFactory } = require('@/modules/core/repositories/server') +const { getEventBus } = require('@/modules/shared/services/eventBus') const getUsers = legacyGetPaginatedUsersFactory({ db }) const countUsers = legacyGetPaginatedUsersCountFactory({ db }) @@ -83,7 +83,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const deleteUser = deleteUserFactory({ deleteStream: deleteStreamFactory({ db }), diff --git a/packages/server/modules/core/tests/usersAdminList.spec.ts b/packages/server/modules/core/tests/usersAdminList.spec.ts index 6b310f6bfb..7c87f6a19e 100644 --- a/packages/server/modules/core/tests/usersAdminList.spec.ts +++ b/packages/server/modules/core/tests/usersAdminList.spec.ts @@ -30,7 +30,6 @@ import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/se import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' import { getEventBus } from '@/modules/shared/services/eventBus' import { createBranchFactory } from '@/modules/core/repositories/branches' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { countAdminUsersFactory, getUserFactory, @@ -50,7 +49,6 @@ import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repos import { createUserFactory } from '@/modules/core/services/users/management' import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { getServerInfoFactory } from '@/modules/core/repositories/server' // To ensure that the invites are created in the correct order, we need to wait a bit between each creation @@ -84,7 +82,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const createInviteDirectly = createStreamInviteDirectly @@ -114,7 +112,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) function randomEl(array: T[]): T { diff --git a/packages/server/modules/core/tests/usersGraphql.spec.ts b/packages/server/modules/core/tests/usersGraphql.spec.ts index f43e88f22e..4d10b4f0b1 100644 --- a/packages/server/modules/core/tests/usersGraphql.spec.ts +++ b/packages/server/modules/core/tests/usersGraphql.spec.ts @@ -38,9 +38,9 @@ import { storeUserAclFactory, storeUserFactory } from '@/modules/core/repositories/users' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { createUserFactory } from '@/modules/core/services/users/management' import { getServerInfoFactory } from '@/modules/core/repositories/server' +import { getEventBus } from '@/modules/shared/services/eventBus' const getServerInfo = getServerInfoFactory({ db }) const getUser = getUserFactory({ db }) @@ -72,7 +72,7 @@ const createUser = createUserFactory({ countAdminUsers: countAdminUsersFactory({ db }), storeUserAcl: storeUserAclFactory({ db }), validateAndCreateUserEmail: createUserEmail, - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('Users (GraphQL)', () => { diff --git a/packages/server/modules/cross-server-sync/index.ts b/packages/server/modules/cross-server-sync/index.ts index f524eadaf7..e1c3b8ad67 100644 --- a/packages/server/modules/cross-server-sync/index.ts +++ b/packages/server/modules/cross-server-sync/index.ts @@ -22,7 +22,6 @@ import { createCommentReplyAndNotifyFactory, createCommentThreadAndNotifyFactory } from '@/modules/comments/services/management' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { VersionsEmitter } from '@/modules/core/events/versionsEmitter' import { createBranchFactory, @@ -76,6 +75,7 @@ import { downloadCommitFactory } from '@/modules/cross-server-sync/services/comm import { ensureOnboardingProjectFactory } from '@/modules/cross-server-sync/services/onboardingProject' import { downloadProjectFactory } from '@/modules/cross-server-sync/services/project' import { SpeckleModule } from '@/modules/shared/helpers/typeHelper' +import { getEventBus } from '@/modules/shared/services/eventBus' import { publish } from '@/modules/shared/utils/subscriptions' const crossServerSyncModule: SpeckleModule = { @@ -174,7 +174,7 @@ const crossServerSyncModule: SpeckleModule = { deleteProject: deleteProjectFactory({ db }), storeModel: storeModelFactory({ db }), storeProjectRole: storeProjectRoleFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) const ensureOnboardingProject = ensureOnboardingProjectFactory({ diff --git a/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts b/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts index c15ca76b73..fce77ec0a1 100644 --- a/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts +++ b/packages/server/modules/fileuploads/tests/fileuploads.integration.spec.ts @@ -30,7 +30,6 @@ import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/se import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' import { getEventBus } from '@/modules/shared/services/eventBus' import { createBranchFactory } from '@/modules/core/repositories/branches' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { countAdminUsersFactory, getUserFactory, @@ -49,7 +48,6 @@ import { renderEmail } from '@/modules/emails/services/emailRendering' import { createUserFactory } from '@/modules/core/services/users/management' import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { sendEmail } from '@/modules/emails/services/sending' import { createTokenFactory } from '@/modules/core/services/tokens' import { @@ -87,7 +85,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) @@ -116,7 +114,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createToken = createTokenFactory({ storeApiToken: storeApiTokenFactory({ db }), diff --git a/packages/server/modules/pwdreset/tests/pwdrest.spec.js b/packages/server/modules/pwdreset/tests/pwdrest.spec.js index fa34725002..9fab02602f 100644 --- a/packages/server/modules/pwdreset/tests/pwdrest.spec.js +++ b/packages/server/modules/pwdreset/tests/pwdrest.spec.js @@ -37,8 +37,8 @@ const { deleteServerOnlyInvitesFactory, updateAllInviteTargetsFactory } = require('@/modules/serverinvites/repositories/serverInvites') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') +const { getEventBus } = require('@/modules/shared/services/eventBus') const db = knex const getServerInfo = getServerInfoFactory({ db }) @@ -67,7 +67,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) describe('Password reset requests @passwordresets', () => { diff --git a/packages/server/modules/serverinvites/domain/events.ts b/packages/server/modules/serverinvites/domain/events.ts index 08447c10cc..ec1bb1df9f 100644 --- a/packages/server/modules/serverinvites/domain/events.ts +++ b/packages/server/modules/serverinvites/domain/events.ts @@ -10,9 +10,6 @@ export const ServerInvitesEvents = { Canceled: `${prefix}canceled` } as const -export type ServerInvitesEventsKeys = - (typeof ServerInvitesEvents)[keyof typeof ServerInvitesEvents] - export type ServerInvitesEventsPayloads = { [ServerInvitesEvents.Created]: { invite: ServerInviteRecord diff --git a/packages/server/modules/shared/services/eventBus.ts b/packages/server/modules/shared/services/eventBus.ts index 2ea5529e37..1d7cc3b864 100644 --- a/packages/server/modules/shared/services/eventBus.ts +++ b/packages/server/modules/shared/services/eventBus.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { WorkspaceEventsPayloads, workspaceEventNamespace @@ -14,6 +15,18 @@ import { serverinvitesEventNamespace, ServerInvitesEventsPayloads } from '@/modules/serverinvites/domain/events' +import { + modelEventsNamespace, + ModelEventsPayloads +} from '@/modules/core/domain/branches/events' +import { + projectEventsNamespace, + ProjectEventsPayloads +} from '@/modules/core/domain/projects/events' +import { + userEventsNamespace, + UserEventsPayloads +} from '@/modules/core/domain/users/events' type AllEventsWildcard = '**' type EventWildcard = '*' @@ -34,6 +47,9 @@ type EventsByNamespace = { [workspaceEventNamespace]: WorkspaceEventsPayloads [gatekeeperEventNamespace]: GatekeeperEventPayloads [serverinvitesEventNamespace]: ServerInvitesEventsPayloads + [modelEventsNamespace]: ModelEventsPayloads + [projectEventsNamespace]: ProjectEventsPayloads + [userEventsNamespace]: UserEventsPayloads } type EventTypes = UnionToIntersection @@ -71,7 +87,7 @@ type EventPayloadsByNamespaceMap = { } export type EventPayload = T extends AllEventsWildcard - ? // if event key is "*", get all events from the flat object + ? // if event key is "**", get all events from the flat object EventPayloadsMap[keyof EventPayloadsMap] : // else if, the key is a "namespace.*" wildcard T extends `${infer Namespace}.${EventWildcard}` @@ -143,3 +159,10 @@ export function getEventBus(): EventBus { if (!eventBus) eventBus = initializeEventBus() return eventBus } + +export const isSpecificEventPayload = ( + payload: EventPayload, + eventKey: EventName +): payload is EventPayload => { + return payload.eventName === eventKey +} diff --git a/packages/server/modules/stats/tests/stats.spec.ts b/packages/server/modules/stats/tests/stats.spec.ts index d74eeb13f0..e89aa4ef03 100644 --- a/packages/server/modules/stats/tests/stats.spec.ts +++ b/packages/server/modules/stats/tests/stats.spec.ts @@ -51,7 +51,6 @@ import { import { collectAndValidateCoreTargetsFactory } from '@/modules/serverinvites/services/coreResourceCollection' import { buildCoreInviteEmailContentsFactory } from '@/modules/serverinvites/services/coreEmailContents' import { getEventBus } from '@/modules/shared/services/eventBus' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { saveActivityFactory } from '@/modules/activitystream/repositories' import { publish } from '@/modules/shared/utils/subscriptions' import { addCommitCreatedActivityFactory } from '@/modules/activitystream/services/commitActivity' @@ -74,7 +73,6 @@ import { sendEmail } from '@/modules/emails/services/sending' import { createUserFactory } from '@/modules/core/services/users/management' import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { createPersonalAccessTokenFactory } from '@/modules/core/services/tokens' import { storeApiTokenFactory, @@ -135,7 +133,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const findEmail = findEmailFactory({ db }) @@ -163,7 +161,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ storeApiToken: storeApiTokenFactory({ db }), diff --git a/packages/server/modules/webhooks/tests/cleanup.spec.ts b/packages/server/modules/webhooks/tests/cleanup.spec.ts index 0d287bd477..9598d19723 100644 --- a/packages/server/modules/webhooks/tests/cleanup.spec.ts +++ b/packages/server/modules/webhooks/tests/cleanup.spec.ts @@ -1,6 +1,4 @@ import knex, { db } from '@/db/knex' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { createRandomEmail, createRandomPassword @@ -85,7 +83,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const findEmail = findEmailFactory({ db }) @@ -113,7 +111,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const countWebhooks = async () => { diff --git a/packages/server/modules/webhooks/tests/webhooks.spec.js b/packages/server/modules/webhooks/tests/webhooks.spec.js index 6bc57fee09..0c8001a165 100644 --- a/packages/server/modules/webhooks/tests/webhooks.spec.js +++ b/packages/server/modules/webhooks/tests/webhooks.spec.js @@ -56,7 +56,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUserFactory, getUsersFactory, @@ -84,7 +83,6 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { createPersonalAccessTokenFactory } = require('@/modules/core/services/tokens') const { storeApiTokenFactory, @@ -126,7 +124,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const grantPermissionsStream = grantStreamPermissionsFactory({ db }) @@ -155,7 +153,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ storeApiToken: storeApiTokenFactory({ db }), diff --git a/packages/server/modules/workspaces/events/eventListener.ts b/packages/server/modules/workspaces/events/eventListener.ts index 614440316e..0154542c24 100644 --- a/packages/server/modules/workspaces/events/eventListener.ts +++ b/packages/server/modules/workspaces/events/eventListener.ts @@ -1,8 +1,3 @@ -import { - ProjectsEmitter, - ProjectEvents, - ProjectEventsPayloads -} from '@/modules/core/events/projectsEmitter' import { deleteProjectRoleFactory, getStreamFactory, @@ -62,6 +57,10 @@ import { import { WorkspacesNotAuthorizedError } from '@/modules/workspaces/errors/workspace' import { publish, WorkspaceSubscriptions } from '@/modules/shared/utils/subscriptions' import { isWorkspaceResourceTarget } from '@/modules/workspaces/services/invites' +import { + ProjectEvents, + ProjectEventsPayloads +} from '@/modules/core/domain/projects/events' export const onProjectCreatedFactory = ({ @@ -318,7 +317,7 @@ export const initializeEventListenersFactory = }) const quitCbs = [ - ProjectsEmitter.listen(ProjectEvents.Created, async (payload) => { + eventBus.listen(ProjectEvents.Created, async ({ payload }) => { const onProjectCreated = onProjectCreatedFactory({ getWorkspaceRoleToDefaultProjectRoleMapping: getWorkspaceRoleToDefaultProjectRoleMappingFactory({ diff --git a/packages/server/modules/workspaces/rest/sso.ts b/packages/server/modules/workspaces/rest/sso.ts index 405461e0f5..01525032cb 100644 --- a/packages/server/modules/workspaces/rest/sso.ts +++ b/packages/server/modules/workspaces/rest/sso.ts @@ -73,7 +73,6 @@ import { import { createUserFactory } from '@/modules/core/services/users/management' import { getServerInfoFactory } from '@/modules/core/repositories/server' import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' @@ -118,6 +117,7 @@ import { canWorkspaceUseOidcSsoFactory } from '@/modules/gatekeeper/services/fea import { getWorkspacePlanFactory } from '@/modules/gatekeeper/repositories/billing' import cryptoRandomString from 'crypto-random-string' import { base64Encode } from '@/modules/shared/helpers/cryptoHelper' +import { getEventBus } from '@/modules/shared/services/eventBus' const moveAuthParamsToSessionMiddleware = moveAuthParamsToSessionMiddlewareFactory() const sessionMiddleware = sessionMiddlewareFactory() @@ -312,7 +312,7 @@ export const getSsoRouter = (): Router => { sendEmail }) }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }), upsertWorkspaceRole: upsertWorkspaceRoleFactory({ db: trx }), findInvite: findInviteFactory({ db: trx }), diff --git a/packages/server/modules/workspaces/services/projects.ts b/packages/server/modules/workspaces/services/projects.ts index 886a28c99c..e9334e10f1 100644 --- a/packages/server/modules/workspaces/services/projects.ts +++ b/packages/server/modules/workspaces/services/projects.ts @@ -43,8 +43,8 @@ import { } from '@/modules/core/repositories/projects' import { mainDb } from '@/db/knex' import { storeModelFactory } from '@/modules/core/repositories/models' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { getProjectFactory } from '@/modules/core/repositories/streams' +import { getEventBus } from '@/modules/shared/services/eventBus' export const queryAllWorkspaceProjectsFactory = ({ getStreams @@ -278,7 +278,7 @@ export const createWorkspaceProjectFactory = storeModel: storeModelFactory({ db: projectDb }), // THIS MUST GO TO THE MAIN DB storeProjectRole: storeProjectRoleFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) const project = await createNewProject({ diff --git a/packages/server/scripts/seedUsers.js b/packages/server/scripts/seedUsers.js index d668549f5a..610c8b439b 100644 --- a/packages/server/scripts/seedUsers.js +++ b/packages/server/scripts/seedUsers.js @@ -1,7 +1,6 @@ require('../bootstrap') const { db } = require('@/db/knex') const { logger } = require('@/logging/logging') -const { UsersEmitter } = require('@/modules/core/events/usersEmitter') const { getServerInfoFactory } = require('@/modules/core/repositories/server') const { findEmailFactory, @@ -33,6 +32,7 @@ const { const { finalizeInvitedServerRegistrationFactory } = require('@/modules/serverinvites/services/processing') +const { getEventBus } = require('@/modules/shared/services/eventBus') const axios = require('axios').default const getServerInfo = getServerInfoFactory({ db }) @@ -61,7 +61,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const main = async () => { diff --git a/packages/server/scripts/streamObjects.js b/packages/server/scripts/streamObjects.js index fa39ca45c9..544ed287e6 100644 --- a/packages/server/scripts/streamObjects.js +++ b/packages/server/scripts/streamObjects.js @@ -33,7 +33,6 @@ const { } = require('@/modules/serverinvites/services/coreEmailContents') const { getEventBus } = require('@/modules/shared/services/eventBus') const { createBranchFactory } = require('@/modules/core/repositories/branches') -const { ProjectsEmitter } = require('@/modules/core/events/projectsEmitter') const { getUsersFactory, getUserFactory, @@ -76,7 +75,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) }) const getUserByEmail = legacyGetUserByEmailFactory({ db }) diff --git a/packages/server/test/authHelper.ts b/packages/server/test/authHelper.ts index eb5994123b..72db85041b 100644 --- a/packages/server/test/authHelper.ts +++ b/packages/server/test/authHelper.ts @@ -1,5 +1,4 @@ import { db } from '@/db/knex' -import { UsersEmitter } from '@/modules/core/events/usersEmitter' import { AllScopes, ServerRoles } from '@/modules/core/helpers/mainConstants' import { UserRecord } from '@/modules/core/helpers/types' import { getServerInfoFactory } from '@/modules/core/repositories/server' @@ -32,6 +31,7 @@ import { updateAllInviteTargetsFactory } from '@/modules/serverinvites/repositories/serverInvites' import { finalizeInvitedServerRegistrationFactory } from '@/modules/serverinvites/services/processing' +import { getEventBus } from '@/modules/shared/services/eventBus' import { faker } from '@faker-js/faker' import { ServerScope, wait } from '@speckle/shared' import { isArray, isNumber, kebabCase, omit, times } from 'lodash' @@ -62,7 +62,7 @@ const createUser = createUserFactory({ }), requestNewEmailVerification }), - usersEventsEmitter: UsersEmitter.emit + emitEvent: getEventBus().emit }) const createPersonalAccessToken = createPersonalAccessTokenFactory({ storeApiToken: storeApiTokenFactory({ db }), diff --git a/packages/server/test/speckle-helpers/streamHelper.ts b/packages/server/test/speckle-helpers/streamHelper.ts index 65b0dee1c4..6414e35cad 100644 --- a/packages/server/test/speckle-helpers/streamHelper.ts +++ b/packages/server/test/speckle-helpers/streamHelper.ts @@ -6,7 +6,6 @@ import { addStreamPermissionsRevokedActivityFactory } from '@/modules/activitystream/services/streamActivity' import { StreamAcl } from '@/modules/core/dbSchema' -import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter' import { StreamAclRecord, StreamRecord } from '@/modules/core/helpers/types' import { createBranchFactory } from '@/modules/core/repositories/branches' import { getServerInfoFactory } from '@/modules/core/repositories/server' @@ -76,7 +75,7 @@ const createStream = legacyCreateStreamFactory({ }), createStream: createStreamFactory({ db }), createBranch: createBranchFactory({ db }), - projectsEventsEmitter: ProjectsEmitter.emit + emitEvent: getEventBus().emit }) })