From 96baa72ecdcc824430491983bdf2f4af48fa9dfb Mon Sep 17 00:00:00 2001 From: Leonardo Cartaxo Date: Tue, 11 Oct 2022 14:40:41 -0300 Subject: [PATCH 1/8] feat: added org invitation (WIP) --- package.json | 2 +- .../invitation.controller.e2e-spec.ts | 9 +- .../invitation-acceptance.service.spec.ts | 10 +- .../invitation-revocation.service.spec.ts | 6 +- .../services/invitation-send.service.spec.ts | 11 +- packages/nestjs-org/package.json | 2 + .../src/__fixtures__/org-entity.fixture.ts | 7 +- .../__fixtures__/org-member.entity.fixture.ts | 18 +++ .../src/__fixtures__/user-entity.fixture.ts | 10 ++ .../entities/org-member-postgres.entity.ts | 33 ++++++ .../src/entities/org-member-sqlite.entity.ts | 33 ++++++ .../src/exceptions/org-member.exception.ts | 9 ++ .../src/exceptions/org-not-found.exception.ts | 9 ++ .../org-member-creatable.interface.ts | 4 + .../interfaces/org-member-entity.interface.ts | 3 + .../org-member-lookup-service.interface.ts | 13 +++ .../org-member-mutate-service.interface.ts | 10 ++ .../org-member-updatable.interface.ts | 4 + .../src/interfaces/org-settings.interface.ts | 12 +- .../listeners/invitation-accepted-listener.ts | 105 ++++++++++++++++++ packages/nestjs-org/src/org.constants.ts | 1 + packages/nestjs-org/src/org.module.spec.ts | 9 +- packages/nestjs-org/src/org.module.ts | 11 +- .../src/services/org-member-lookup.service.ts | 24 ++++ .../src/services/org-member-mutate.service.ts | 34 ++++++ .../listeners/invitation-accepted-listener.ts | 7 +- packages/ts-common/src/index.ts | 6 + .../src/invitation/invitation.contants.ts | 2 + .../org/interfaces/org-member.interface.ts | 13 +++ .../src/org/interfaces/org.interface.ts | 2 + .../src/services/base.service.ts | 4 +- .../src/services/lookup.service.ts | 1 + 32 files changed, 400 insertions(+), 24 deletions(-) create mode 100644 packages/nestjs-org/src/__fixtures__/org-member.entity.fixture.ts create mode 100644 packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts create mode 100644 packages/nestjs-org/src/entities/org-member-postgres.entity.ts create mode 100644 packages/nestjs-org/src/entities/org-member-sqlite.entity.ts create mode 100644 packages/nestjs-org/src/exceptions/org-member.exception.ts create mode 100644 packages/nestjs-org/src/exceptions/org-not-found.exception.ts create mode 100644 packages/nestjs-org/src/interfaces/org-member-creatable.interface.ts create mode 100644 packages/nestjs-org/src/interfaces/org-member-entity.interface.ts create mode 100644 packages/nestjs-org/src/interfaces/org-member-lookup-service.interface.ts create mode 100644 packages/nestjs-org/src/interfaces/org-member-mutate-service.interface.ts create mode 100644 packages/nestjs-org/src/interfaces/org-member-updatable.interface.ts create mode 100644 packages/nestjs-org/src/listeners/invitation-accepted-listener.ts create mode 100644 packages/nestjs-org/src/services/org-member-lookup.service.ts create mode 100644 packages/nestjs-org/src/services/org-member-mutate.service.ts create mode 100644 packages/ts-common/src/invitation/invitation.contants.ts create mode 100644 packages/ts-common/src/org/interfaces/org-member.interface.ts diff --git a/package.json b/package.json index 41272646f..d93ed835e 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "watch": "yarn build && ./node_modules/.bin/tsc --build --watch", "lint": "eslint \"./*.json\" \"packages/*/src/**/*.{ts,js,json}\" --fix", "test": "jest --testTimeout 30000", - "test:one": "jest --testTimeout 30000 packages/nestjs-invitation/src/services/invitation.service.spec.ts", + "test:one": "jest --testTimeout 30000 packages/nestjs-org/src/org.module.spec.ts", "prepare": "husky install && yarn clean && yarn build", "test:watch": "jest --watch", "test:cov": "jest --coverage", diff --git a/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts b/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts index 724af2fa8..d8519ea8b 100644 --- a/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts +++ b/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts @@ -4,7 +4,11 @@ import { INestApplication } from '@nestjs/common'; import { UserFactory } from '@concepta/nestjs-user/src/seeding'; import { ConfigService, ConfigType } from '@nestjs/config'; import { OtpService } from '@concepta/nestjs-otp'; -import { OtpInterface, UserInterface } from '@concepta/ts-common'; +import { + INVITATION_MODULE_CATEGORY_USER_KEY, + OtpInterface, + UserInterface, +} from '@concepta/ts-common'; import { EmailService } from '@concepta/nestjs-email'; import { SeedingSource } from '@concepta/typeorm-seeding'; import { getDataSourceToken } from '@nestjs/typeorm'; @@ -17,13 +21,12 @@ import { invitationDefaultConfig } from '../config/invitation-default.config'; import { InvitationFactory } from '../invitation.factory'; import { InvitationEntityInterface } from '../interfaces/invitation.entity.interface'; import { InvitationSettingsInterface } from '../interfaces/invitation-settings.interface'; - import { AppModuleFixture } from '../__fixtures__/app.module.fixture'; import { InvitationEntityFixture } from '../__fixtures__/invitation/entities/invitation.entity.fixture'; import { UserEntityFixture } from '../__fixtures__/user/entities/user-entity.fixture'; describe('InvitationController (e2e)', () => { - const category = 'invitation'; + const category = INVITATION_MODULE_CATEGORY_USER_KEY; const payload = { moreData: 'foo' }; let app: INestApplication; diff --git a/packages/nestjs-invitation/src/services/invitation-acceptance.service.spec.ts b/packages/nestjs-invitation/src/services/invitation-acceptance.service.spec.ts index d6e714697..f4fe916e3 100644 --- a/packages/nestjs-invitation/src/services/invitation-acceptance.service.spec.ts +++ b/packages/nestjs-invitation/src/services/invitation-acceptance.service.spec.ts @@ -1,7 +1,11 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { getDataSourceToken } from '@nestjs/typeorm'; -import { OtpInterface, UserInterface } from '@concepta/ts-common'; +import { + INVITATION_MODULE_CATEGORY_USER_KEY, + OtpInterface, + UserInterface, +} from '@concepta/ts-common'; import { UserEntityInterface } from '@concepta/nestjs-user'; import { OtpService } from '@concepta/nestjs-otp'; import { UserFactory } from '@concepta/nestjs-user/src/seeding'; @@ -10,18 +14,16 @@ import { EmailService } from '@concepta/nestjs-email'; import { EventDispatchService } from '@concepta/nestjs-event'; import { INVITATION_MODULE_SETTINGS_TOKEN } from '../invitation.constants'; - import { InvitationFactory } from '../invitation.factory'; import { InvitationSettingsInterface } from '../interfaces/invitation-settings.interface'; import { InvitationEntityInterface } from '../interfaces/invitation.entity.interface'; import { InvitationAcceptanceService } from './invitation-acceptance.service'; - import { AppModuleFixture } from '../__fixtures__/app.module.fixture'; import { InvitationEntityFixture } from '../__fixtures__/invitation/entities/invitation.entity.fixture'; import { UserEntityFixture } from '../__fixtures__/user/entities/user-entity.fixture'; describe(InvitationAcceptanceService, () => { - const category = 'invitation'; + const category = INVITATION_MODULE_CATEGORY_USER_KEY; let spyEmailService: jest.SpyInstance; let spyEventDispatchService: jest.SpyInstance; diff --git a/packages/nestjs-invitation/src/services/invitation-revocation.service.spec.ts b/packages/nestjs-invitation/src/services/invitation-revocation.service.spec.ts index a47684b50..6d4ec2f66 100644 --- a/packages/nestjs-invitation/src/services/invitation-revocation.service.spec.ts +++ b/packages/nestjs-invitation/src/services/invitation-revocation.service.spec.ts @@ -2,27 +2,25 @@ import { Repository } from 'typeorm'; import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { getDataSourceToken } from '@nestjs/typeorm'; - import { UserEntityInterface } from '@concepta/nestjs-user'; import { OtpService } from '@concepta/nestjs-otp'; import { EmailService } from '@concepta/nestjs-email'; import { UserFactory } from '@concepta/nestjs-user/src/seeding'; import { SeedingSource } from '@concepta/typeorm-seeding'; import { getDynamicRepositoryToken } from '@concepta/nestjs-typeorm-ext'; +import { INVITATION_MODULE_CATEGORY_USER_KEY } from '@concepta/ts-common'; import { INVITATION_MODULE_INVITATION_ENTITY_KEY } from '../invitation.constants'; - import { InvitationFactory } from '../invitation.factory'; import { InvitationSendService } from './invitation-send.service'; import { InvitationRevocationService } from './invitation-revocation.service'; import { InvitationEntityInterface } from '../interfaces/invitation.entity.interface'; - import { AppModuleFixture } from '../__fixtures__/app.module.fixture'; import { InvitationEntityFixture } from '../__fixtures__/invitation/entities/invitation.entity.fixture'; import { UserEntityFixture } from '../__fixtures__/user/entities/user-entity.fixture'; describe(InvitationRevocationService, () => { - const category = 'invitation'; + const category = INVITATION_MODULE_CATEGORY_USER_KEY; let spyEmailService: jest.SpyInstance; diff --git a/packages/nestjs-invitation/src/services/invitation-send.service.spec.ts b/packages/nestjs-invitation/src/services/invitation-send.service.spec.ts index 36a2f4630..976fa8133 100644 --- a/packages/nestjs-invitation/src/services/invitation-send.service.spec.ts +++ b/packages/nestjs-invitation/src/services/invitation-send.service.spec.ts @@ -3,17 +3,16 @@ import { Repository } from 'typeorm'; import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { getDataSourceToken } from '@nestjs/typeorm'; - import { UserEntityInterface } from '@concepta/nestjs-user'; import { EmailService } from '@concepta/nestjs-email'; import { getDynamicRepositoryToken } from '@concepta/nestjs-typeorm-ext'; import { SeedingSource } from '@concepta/typeorm-seeding'; import { UserFactory } from '@concepta/nestjs-user/src/seeding'; +import { INVITATION_MODULE_CATEGORY_USER_KEY } from '@concepta/ts-common'; import { INVITATION_MODULE_SETTINGS_TOKEN } from '../invitation.constants'; import { InvitationSendService } from './invitation-send.service'; import { InvitationSettingsInterface } from '../interfaces/invitation-settings.interface'; - import { AppModuleFixture } from '../__fixtures__/app.module.fixture'; import { UserEntityFixture } from '../__fixtures__/user/entities/user-entity.fixture'; import { UserOtpEntityFixture } from '../__fixtures__/user/entities/user-otp-entity.fixture'; @@ -73,14 +72,18 @@ describe(InvitationSendService, () => { it('Should send invitation email', async () => { const inviteCode = randomUUID(); - await invitationSendService.send(testUser, inviteCode, 'invitation'); + await invitationSendService.send( + testUser, + inviteCode, + INVITATION_MODULE_CATEGORY_USER_KEY, + ); const otps = await userOtpRepo.find({ where: { assignee: { id: testUser.id } }, }); expect(otps.length).toEqual(1); - expect(otps[0].category).toEqual('invitation'); + expect(otps[0].category).toEqual(INVITATION_MODULE_CATEGORY_USER_KEY); expect(spyEmailService).toHaveBeenCalledTimes(1); const { passcode, expirationDate } = otps[0]; diff --git a/packages/nestjs-org/package.json b/packages/nestjs-org/package.json index 5c5e2cfc9..3a021ba53 100644 --- a/packages/nestjs-org/package.json +++ b/packages/nestjs-org/package.json @@ -15,6 +15,8 @@ "@concepta/nestjs-access-control": "^4.0.0-alpha.20", "@concepta/nestjs-common": "^4.0.0-alpha.20", "@concepta/nestjs-crud": "^4.0.0-alpha.20", + "@concepta/nestjs-event": "^4.0.0-alpha.20", + "@concepta/nestjs-user": "^4.0.0-alpha.20", "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.20", "@concepta/ts-common": "^4.0.0-alpha.20", "@concepta/ts-core": "^4.0.0-alpha.20", diff --git a/packages/nestjs-org/src/__fixtures__/org-entity.fixture.ts b/packages/nestjs-org/src/__fixtures__/org-entity.fixture.ts index f3343ac56..d10b93535 100644 --- a/packages/nestjs-org/src/__fixtures__/org-entity.fixture.ts +++ b/packages/nestjs-org/src/__fixtures__/org-entity.fixture.ts @@ -1,6 +1,8 @@ -import { Entity, ManyToOne } from 'typeorm'; +import { Entity, ManyToOne, OneToMany } from 'typeorm'; + import { OrgSqliteEntity } from '../entities/org-sqlite.entity'; import { OwnerEntityFixture } from './owner-entity.fixture'; +import { OrgMemberEntityFixture } from './org-member.entity.fixture'; /** * Org Entity Fixture @@ -9,4 +11,7 @@ import { OwnerEntityFixture } from './owner-entity.fixture'; export class OrgEntityFixture extends OrgSqliteEntity { @ManyToOne(() => OwnerEntityFixture, (user) => user.orgs, { nullable: false }) owner!: OwnerEntityFixture; + + @OneToMany(() => OrgMemberEntityFixture, (orgMember) => orgMember.org) + orgMembers!: OrgMemberEntityFixture[]; } diff --git a/packages/nestjs-org/src/__fixtures__/org-member.entity.fixture.ts b/packages/nestjs-org/src/__fixtures__/org-member.entity.fixture.ts new file mode 100644 index 000000000..975acb840 --- /dev/null +++ b/packages/nestjs-org/src/__fixtures__/org-member.entity.fixture.ts @@ -0,0 +1,18 @@ +import { Entity, ManyToOne } from 'typeorm'; + +import { UserEntityFixture } from './user-entity.fixture'; +import { OrgEntityFixture } from './org-entity.fixture'; +import { OrgMemberSqliteEntity } from '../entities/org-member-sqlite.entity'; + +@Entity() +export class OrgMemberEntityFixture extends OrgMemberSqliteEntity { + @ManyToOne(() => OrgEntityFixture, (org) => org.orgMembers, { + nullable: false, + }) + org!: OrgEntityFixture; + + @ManyToOne(() => UserEntityFixture, (user) => user.orgMembers, { + nullable: false, + }) + user!: UserEntityFixture; +} diff --git a/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts b/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts new file mode 100644 index 000000000..6e1ef703a --- /dev/null +++ b/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts @@ -0,0 +1,10 @@ +import { Entity, OneToMany } from 'typeorm'; +import { UserSqliteEntity } from '@concepta/nestjs-user'; + +import { OrgMemberEntityFixture } from './org-member.entity.fixture'; + +@Entity() +export class UserEntityFixture extends UserSqliteEntity { + @OneToMany(() => OrgMemberEntityFixture, (orgMember) => orgMember.org) + orgMembers!: OrgMemberEntityFixture[]; +} diff --git a/packages/nestjs-org/src/entities/org-member-postgres.entity.ts b/packages/nestjs-org/src/entities/org-member-postgres.entity.ts new file mode 100644 index 000000000..5e9d0e573 --- /dev/null +++ b/packages/nestjs-org/src/entities/org-member-postgres.entity.ts @@ -0,0 +1,33 @@ +import { Column, PrimaryGeneratedColumn, Unique } from 'typeorm'; +import { + AuditInterface, + ReferenceId, + ReferenceIdInterface, +} from '@concepta/ts-core'; +import { AuditPostgresEmbed } from '@concepta/typeorm-common'; + +import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; + +@Unique(['userId', 'orgId']) +export abstract class OrgMemberPostgresEntity + implements OrgMemberEntityInterface +{ + @PrimaryGeneratedColumn('uuid') + id!: ReferenceId; + + @Column(() => AuditPostgresEmbed, {}) + audit!: AuditInterface; + + @Column('boolean', { default: true }) + active = true; + + @Column() + userId!: ReferenceId; + + @Column() + orgId!: ReferenceId; + + user!: ReferenceIdInterface; + + org!: ReferenceIdInterface; +} diff --git a/packages/nestjs-org/src/entities/org-member-sqlite.entity.ts b/packages/nestjs-org/src/entities/org-member-sqlite.entity.ts new file mode 100644 index 000000000..1a1788988 --- /dev/null +++ b/packages/nestjs-org/src/entities/org-member-sqlite.entity.ts @@ -0,0 +1,33 @@ +import { Column, PrimaryGeneratedColumn, Unique } from 'typeorm'; +import { + AuditInterface, + ReferenceId, + ReferenceIdInterface, +} from '@concepta/ts-core'; +import { AuditSqlLiteEmbed } from '@concepta/typeorm-common'; + +import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; + +@Unique(['userId', 'orgId']) +export abstract class OrgMemberSqliteEntity + implements OrgMemberEntityInterface +{ + @PrimaryGeneratedColumn('uuid') + id!: ReferenceId; + + @Column(() => AuditSqlLiteEmbed, {}) + audit!: AuditInterface; + + @Column('boolean', { default: true }) + active = true; + + @Column() + userId!: ReferenceId; + + @Column() + orgId!: ReferenceId; + + user!: ReferenceIdInterface; + + org!: ReferenceIdInterface; +} diff --git a/packages/nestjs-org/src/exceptions/org-member.exception.ts b/packages/nestjs-org/src/exceptions/org-member.exception.ts new file mode 100644 index 000000000..55f9bbf0a --- /dev/null +++ b/packages/nestjs-org/src/exceptions/org-member.exception.ts @@ -0,0 +1,9 @@ +import { ExceptionInterface } from '@concepta/ts-core'; + +export class OrgMemberException extends Error implements ExceptionInterface { + errorCode = 'ORG_MEMBER_ERROR'; + + constructor(message: string) { + super(message); + } +} diff --git a/packages/nestjs-org/src/exceptions/org-not-found.exception.ts b/packages/nestjs-org/src/exceptions/org-not-found.exception.ts new file mode 100644 index 000000000..5687efb71 --- /dev/null +++ b/packages/nestjs-org/src/exceptions/org-not-found.exception.ts @@ -0,0 +1,9 @@ +import { ExceptionInterface } from '@concepta/ts-core'; + +export class OrgNotFoundException extends Error implements ExceptionInterface { + errorCode = 'ORG_NOT_FOUND_ERROR'; + + constructor(message = 'The org was not found') { + super(message); + } +} diff --git a/packages/nestjs-org/src/interfaces/org-member-creatable.interface.ts b/packages/nestjs-org/src/interfaces/org-member-creatable.interface.ts new file mode 100644 index 000000000..dd8d6e769 --- /dev/null +++ b/packages/nestjs-org/src/interfaces/org-member-creatable.interface.ts @@ -0,0 +1,4 @@ +import { OrgMemberInterface } from '@concepta/ts-common'; + +export interface OrgMemberCreatableInterface + extends Pick {} diff --git a/packages/nestjs-org/src/interfaces/org-member-entity.interface.ts b/packages/nestjs-org/src/interfaces/org-member-entity.interface.ts new file mode 100644 index 000000000..196cd1af5 --- /dev/null +++ b/packages/nestjs-org/src/interfaces/org-member-entity.interface.ts @@ -0,0 +1,3 @@ +import { OrgMemberInterface } from '@concepta/ts-common'; + +export interface OrgMemberEntityInterface extends OrgMemberInterface {} diff --git a/packages/nestjs-org/src/interfaces/org-member-lookup-service.interface.ts b/packages/nestjs-org/src/interfaces/org-member-lookup-service.interface.ts new file mode 100644 index 000000000..11b5e5183 --- /dev/null +++ b/packages/nestjs-org/src/interfaces/org-member-lookup-service.interface.ts @@ -0,0 +1,13 @@ +import { + LookupIdInterface, + ReferenceId, + ReferenceIdInterface, +} from '@concepta/ts-core'; +import { QueryOptionsInterface } from '@concepta/typeorm-common'; + +export interface OrgMemberLookupServiceInterface + extends LookupIdInterface< + ReferenceId, + ReferenceIdInterface, + QueryOptionsInterface + > {} diff --git a/packages/nestjs-org/src/interfaces/org-member-mutate-service.interface.ts b/packages/nestjs-org/src/interfaces/org-member-mutate-service.interface.ts new file mode 100644 index 000000000..b6dc85b3d --- /dev/null +++ b/packages/nestjs-org/src/interfaces/org-member-mutate-service.interface.ts @@ -0,0 +1,10 @@ +import { CreateOneInterface } from '@concepta/ts-core'; + +import { OrgMemberEntityInterface } from './org-member-entity.interface'; +import { OrgMemberCreatableInterface } from './org-member-creatable.interface'; + +export interface OrgMemberMutateServiceInterface + extends CreateOneInterface< + OrgMemberCreatableInterface, + OrgMemberEntityInterface + > {} diff --git a/packages/nestjs-org/src/interfaces/org-member-updatable.interface.ts b/packages/nestjs-org/src/interfaces/org-member-updatable.interface.ts new file mode 100644 index 000000000..2a52c23b5 --- /dev/null +++ b/packages/nestjs-org/src/interfaces/org-member-updatable.interface.ts @@ -0,0 +1,4 @@ +import { OrgMemberInterface } from '@concepta/ts-common'; + +export interface OrgMemberUpdatableInterface + extends Pick {} diff --git a/packages/nestjs-org/src/interfaces/org-settings.interface.ts b/packages/nestjs-org/src/interfaces/org-settings.interface.ts index 50ec426ec..3eb9c2aa8 100644 --- a/packages/nestjs-org/src/interfaces/org-settings.interface.ts +++ b/packages/nestjs-org/src/interfaces/org-settings.interface.ts @@ -1 +1,11 @@ -export interface OrgSettingsInterface {} +import { + EventAsyncInterface, + EventClassInterface, +} from '@concepta/nestjs-event'; +import { InvitationAcceptedEventPayloadInterface } from '@concepta/ts-common'; + +export interface OrgSettingsInterface { + invitationRequestEvent?: EventClassInterface< + EventAsyncInterface + >; +} diff --git a/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts b/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts new file mode 100644 index 000000000..6abeefa98 --- /dev/null +++ b/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts @@ -0,0 +1,105 @@ +import { + EventAsyncInterface, + EventListenerOn, + EventListenService, +} from '@concepta/nestjs-event'; +import { + INVITATION_MODULE_CATEGORY_ORG_KEY, + InvitationAcceptedEventPayloadInterface, +} from '@concepta/ts-common'; +import { Inject, Injectable, OnModuleInit, Optional } from '@nestjs/common'; + +import { ORG_MODULE_SETTINGS_TOKEN } from '../org.constants'; +import { OrgSettingsInterface } from '../interfaces/org-settings.interface'; +import { OrgMemberMutateService } from '../services/org-member-mutate.service'; +import { OrgLookupService } from '../services/org-lookup.service'; +import { OrgMemberException } from '../exceptions/org-member.exception'; +import { OrgNotFoundException } from '../exceptions/org-not-found.exception'; +import { UserLookupService } from '@concepta/nestjs-user'; +import { UserNotFoundException } from '@concepta/nestjs-user/dist/exceptions/user-not-found-exception'; +import { OrgMemberLookupService } from '../services/org-member-lookup.service'; + +@Injectable() +export class InvitationAcceptedListener + extends EventListenerOn< + EventAsyncInterface + > + implements OnModuleInit +{ + constructor( + @Inject(ORG_MODULE_SETTINGS_TOKEN) + private settings: OrgSettingsInterface, + private orgLookupService: OrgLookupService, + private userLookupService: UserLookupService, + private orgMemberLookupService: OrgMemberLookupService, + private orgMemberMutateService: OrgMemberMutateService, + @Optional() + @Inject(EventListenService) + private eventListenService?: EventListenService, + ) { + super(); + } + + onModuleInit() { + if (this.eventListenService && this.settings.invitationRequestEvent) { + this.eventListenService.on(this.settings.invitationRequestEvent, this); + } + } + + async listen( + event: EventAsyncInterface< + InvitationAcceptedEventPayloadInterface, + boolean + >, + ) { + // check only for invitation of type category + if (event.payload.category === INVITATION_MODULE_CATEGORY_ORG_KEY) { + const { userId, orgId } = event?.payload.data ?? {}; + + if (typeof userId !== 'string' || typeof orgId !== 'string') { + throw new OrgMemberException( + 'The invitation accepted event payload received has invalid content. The payload must have the "userId" and "orgId" properties.', + ); + } + + const org = await this.orgLookupService.byId( + orgId, + event.payload?.queryOptions, + ); + + if (!org) { + throw new OrgNotFoundException(); + } + + const user = await this.userLookupService.byId( + userId, + event.payload?.queryOptions, + ); + + if (!user) { + throw new UserNotFoundException(); + } + + const orgMember = await this.orgMemberLookupService.findOne( + { where: { orgId, userId } }, + event.payload?.queryOptions, + ); + + if (orgMember) { + throw new OrgMemberException( + `Can't create OrgMember, the the combination of userid: ${userId} and orgId: ${orgId} already exists`, + ); + } + + await this.orgMemberMutateService.create( + { orgId, userId }, + event.payload?.queryOptions, + ); + + return true; + } + + // return true by default + return true; + } +} diff --git a/packages/nestjs-org/src/org.constants.ts b/packages/nestjs-org/src/org.constants.ts index e88444a11..fa0a82c53 100644 --- a/packages/nestjs-org/src/org.constants.ts +++ b/packages/nestjs-org/src/org.constants.ts @@ -4,3 +4,4 @@ export const ORG_MODULE_DEFAULT_SETTINGS_TOKEN = export const ORG_MODULE_OWNER_LOOKUP_SERVICE_TOKEN = 'ORG_MODULE_OWNER_LOOKUP_SERVICE_TOKEN'; export const ORG_MODULE_ORG_ENTITY_KEY = 'org'; +export const MODULE_ORG_MEMBER_ENTITY_KEY = 'orgMember'; diff --git a/packages/nestjs-org/src/org.module.spec.ts b/packages/nestjs-org/src/org.module.spec.ts index 18a1981fd..593dac570 100644 --- a/packages/nestjs-org/src/org.module.spec.ts +++ b/packages/nestjs-org/src/org.module.spec.ts @@ -20,6 +20,8 @@ import { OrgEntityFixture } from './__fixtures__/org-entity.fixture'; import { OwnerEntityFixture } from './__fixtures__/owner-entity.fixture'; import { OwnerLookupServiceFixture } from './__fixtures__/owner-lookup-service.fixture'; import { OwnerModuleFixture } from './__fixtures__/owner.module.fixture'; +import { OrgMemberEntityFixture } from './__fixtures__/org-member.entity.fixture'; +import { UserEntityFixture } from './__fixtures__/user-entity.fixture'; describe('OrgModule', () => { let orgModule: OrgModule; @@ -37,7 +39,12 @@ describe('OrgModule', () => { TypeOrmExtModule.forRoot({ type: 'sqlite', database: ':memory:', - entities: [OrgEntityFixture, OwnerEntityFixture], + entities: [ + OrgEntityFixture, + OwnerEntityFixture, + OrgMemberEntityFixture, + UserEntityFixture, + ], }), OrgModule.forRootAsync({ inject: [OwnerLookupServiceFixture], diff --git a/packages/nestjs-org/src/org.module.ts b/packages/nestjs-org/src/org.module.ts index f10848cd7..e8222400c 100644 --- a/packages/nestjs-org/src/org.module.ts +++ b/packages/nestjs-org/src/org.module.ts @@ -1,4 +1,5 @@ import { DynamicModule, Module } from '@nestjs/common'; + import { OrgController } from './org.controller'; import { OrgLookupService } from './services/org-lookup.service'; import { OrgCrudService } from './services/org-crud.service'; @@ -12,12 +13,20 @@ import { createOrgImports, createOrgProviders, } from './org.module-definition'; +import { OrgMemberMutateService } from './services/org-member-mutate.service'; +import { OrgMemberLookupService } from './services/org-member-lookup.service'; /** * Org Module */ @Module({ - providers: [OrgLookupService, OrgMutateService, OrgCrudService], + providers: [ + OrgLookupService, + OrgMutateService, + OrgCrudService, + OrgMemberLookupService, + OrgMemberMutateService, + ], exports: [OrgLookupService, OrgMutateService, OrgCrudService], controllers: [OrgController], }) diff --git a/packages/nestjs-org/src/services/org-member-lookup.service.ts b/packages/nestjs-org/src/services/org-member-lookup.service.ts new file mode 100644 index 000000000..837ab5129 --- /dev/null +++ b/packages/nestjs-org/src/services/org-member-lookup.service.ts @@ -0,0 +1,24 @@ +import { Repository } from 'typeorm'; +import { Injectable } from '@nestjs/common'; +import { InjectDynamicRepository } from '@concepta/nestjs-typeorm-ext'; +import { LookupService } from '@concepta/typeorm-common'; + +import { MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; +import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; +import { OrgMemberLookupServiceInterface } from '../interfaces/org-member-lookup-service.interface'; + +/** + * Org lookup service + */ +@Injectable() +export class OrgMemberLookupService + extends LookupService + implements OrgMemberLookupServiceInterface +{ + constructor( + @InjectDynamicRepository(MODULE_ORG_MEMBER_ENTITY_KEY) + repo: Repository, + ) { + super(repo); + } +} diff --git a/packages/nestjs-org/src/services/org-member-mutate.service.ts b/packages/nestjs-org/src/services/org-member-mutate.service.ts new file mode 100644 index 000000000..b72785c4d --- /dev/null +++ b/packages/nestjs-org/src/services/org-member-mutate.service.ts @@ -0,0 +1,34 @@ +import { Repository } from 'typeorm'; +import { Injectable } from '@nestjs/common'; +import { MutateService } from '@concepta/typeorm-common'; +import { InjectDynamicRepository } from '@concepta/nestjs-typeorm-ext'; +import { Type } from '@concepta/ts-core'; + +import { OrgMemberMutateServiceInterface } from '../interfaces/org-member-mutate-service.interface'; +import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; +import { MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; +import { OrgMemberCreatableInterface } from '../interfaces/org-member-creatable.interface'; +import { OrgMemberUpdatableInterface } from '../interfaces/org-member-updatable.interface'; + +/** + * User mutate service + */ +@Injectable() +export class OrgMemberMutateService + extends MutateService< + OrgMemberEntityInterface, + OrgMemberCreatableInterface, + OrgMemberUpdatableInterface + > + implements OrgMemberMutateServiceInterface +{ + constructor( + @InjectDynamicRepository(MODULE_ORG_MEMBER_ENTITY_KEY) + repo: Repository, + ) { + super(repo); + } + + protected createDto!: Type; + protected updateDto!: Type; +} diff --git a/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts b/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts index 797ce4858..be0fbe634 100644 --- a/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts +++ b/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts @@ -3,7 +3,10 @@ import { EventListenerOn, EventListenService, } from '@concepta/nestjs-event'; -import { InvitationAcceptedEventPayloadInterface } from '@concepta/ts-common'; +import { + INVITATION_MODULE_CATEGORY_USER_KEY, + InvitationAcceptedEventPayloadInterface, +} from '@concepta/ts-common'; import { Inject, Injectable, OnModuleInit, Optional } from '@nestjs/common'; import { USER_MODULE_SETTINGS_TOKEN } from '../user.constants'; @@ -45,7 +48,7 @@ export class InvitationAcceptedListener >, ) { // check only for invitation of type category - if (event.payload.category === 'invitation') { + if (event.payload.category === INVITATION_MODULE_CATEGORY_USER_KEY) { const { userId, newPassword } = event?.payload.data ?? {}; if (typeof userId !== 'string' || typeof newPassword !== 'string') { diff --git a/packages/ts-common/src/index.ts b/packages/ts-common/src/index.ts index b4b524a0e..bbbc44b96 100644 --- a/packages/ts-common/src/index.ts +++ b/packages/ts-common/src/index.ts @@ -16,6 +16,7 @@ export { OrgInterface } from './org/interfaces/org.interface'; export { OrgOwnerInterface } from './org/interfaces/org-owner.interface'; export { OrgCreatableInterface } from './org/interfaces/org-creatable.interface'; export { OrgUpdatableInterface } from './org/interfaces/org-updatable.interface'; +export { OrgMemberInterface } from './org/interfaces/org-member.interface'; export { UserInterface } from './user/interfaces/user.interface'; export { UserCreatableInterface } from './user/interfaces/user-creatable.interface'; @@ -43,3 +44,8 @@ export { InvitationInterface } from './invitation/interfaces/invitation.interfac export { InvitationAcceptedEventPayloadInterface } from './invitation/interfaces/invitation-accepted-event-payload.interface'; export { InvitationGetUserEventPayloadInterface } from './invitation/interfaces/invitation-get-user-event-payload.interface'; export { InvitationGetUserEventResponseInterface } from './invitation/interfaces/invitation-get-user-event-response.interface'; + +export { + INVITATION_MODULE_CATEGORY_USER_KEY, + INVITATION_MODULE_CATEGORY_ORG_KEY, +} from './invitation/invitation.contants'; diff --git a/packages/ts-common/src/invitation/invitation.contants.ts b/packages/ts-common/src/invitation/invitation.contants.ts new file mode 100644 index 000000000..dafd7d34a --- /dev/null +++ b/packages/ts-common/src/invitation/invitation.contants.ts @@ -0,0 +1,2 @@ +export const INVITATION_MODULE_CATEGORY_USER_KEY = 'user'; +export const INVITATION_MODULE_CATEGORY_ORG_KEY = 'org'; diff --git a/packages/ts-common/src/org/interfaces/org-member.interface.ts b/packages/ts-common/src/org/interfaces/org-member.interface.ts new file mode 100644 index 000000000..a99ef0812 --- /dev/null +++ b/packages/ts-common/src/org/interfaces/org-member.interface.ts @@ -0,0 +1,13 @@ +import { + ReferenceActiveInterface, + ReferenceAuditInterface, + ReferenceIdInterface, +} from '@concepta/ts-core'; + +export interface OrgMemberInterface + extends ReferenceIdInterface, + ReferenceActiveInterface, + ReferenceAuditInterface { + orgId: string; + userId: string; +} diff --git a/packages/ts-common/src/org/interfaces/org.interface.ts b/packages/ts-common/src/org/interfaces/org.interface.ts index 277d42d45..d0c36e63b 100644 --- a/packages/ts-common/src/org/interfaces/org.interface.ts +++ b/packages/ts-common/src/org/interfaces/org.interface.ts @@ -4,6 +4,7 @@ import { ReferenceIdInterface, } from '@concepta/ts-core'; import { OrgOwnerInterface } from './org-owner.interface'; +import { OrgMemberInterface } from './org-member.interface'; export interface OrgInterface extends ReferenceIdInterface, @@ -14,4 +15,5 @@ export interface OrgInterface * Name */ name: string; + members?: OrgMemberInterface; } diff --git a/packages/typeorm-common/src/services/base.service.ts b/packages/typeorm-common/src/services/base.service.ts index f4dae9bba..0928f2d13 100644 --- a/packages/typeorm-common/src/services/base.service.ts +++ b/packages/typeorm-common/src/services/base.service.ts @@ -26,10 +26,10 @@ export abstract class BaseService { /** * Find One wrapper. * - * @private * @param findOneOptions Find options + * @param queryOptions */ - protected async findOne( + async findOne( findOneOptions: FindOneOptions, queryOptions?: QueryOptionsInterface, ): Promise { diff --git a/packages/typeorm-common/src/services/lookup.service.ts b/packages/typeorm-common/src/services/lookup.service.ts index 9ee419115..70c9ef8a3 100644 --- a/packages/typeorm-common/src/services/lookup.service.ts +++ b/packages/typeorm-common/src/services/lookup.service.ts @@ -27,6 +27,7 @@ export abstract class LookupService * Get entity for the given id. * * @param id the id + * @param queryOptions */ async byId( id: ReferenceId, From f08fce9f7197fff0f762c1e0fff91de71d607ed0 Mon Sep 17 00:00:00 2001 From: Leonardo Cartaxo Date: Fri, 21 Oct 2022 10:45:27 -0300 Subject: [PATCH 2/8] feat: fixed org tests --- package.json | 2 +- .../interfaces/org-entities-options.interface.ts | 8 +++++++- packages/nestjs-org/src/org.constants.ts | 2 +- packages/nestjs-org/src/org.controller.e2e-spec.ts | 14 ++++++++++++-- packages/nestjs-org/src/org.module.spec.ts | 3 +++ .../src/services/org-member-lookup.service.ts | 4 ++-- .../src/services/org-member-mutate.service.ts | 4 ++-- 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index efedb01ab..9f3dacd14 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "test:ci": "yarn test:cov --ci --reporters=default --reporters=jest-junit", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./jest.config-e2e.json --testTimeout 30000", - "test:e2e:one": "jest --config ./jest.config-e2e.json --testTimeout 30000 packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts", + "test:e2e:one": "jest --config ./jest.config-e2e.json --testTimeout 30000 packages/nestjs-org/src/org.controller.e2e-spec.ts", "test:all": "yarn test && yarn test:e2e", "doc": "rimraf ./documentation && compodoc -p ./tsconfig.doc.json --disablePrivate --disableProtected", "doc:serve": "yarn doc -s", diff --git a/packages/nestjs-org/src/interfaces/org-entities-options.interface.ts b/packages/nestjs-org/src/interfaces/org-entities-options.interface.ts index f17bec6f7..a2048fa1e 100644 --- a/packages/nestjs-org/src/interfaces/org-entities-options.interface.ts +++ b/packages/nestjs-org/src/interfaces/org-entities-options.interface.ts @@ -1,9 +1,15 @@ import { TypeOrmExtEntityOptionInterface } from '@concepta/nestjs-typeorm-ext'; -import { ORG_MODULE_ORG_ENTITY_KEY } from '../org.constants'; + +import { + ORG_MODULE_ORG_MEMBER_ENTITY_KEY, + ORG_MODULE_ORG_ENTITY_KEY, +} from '../org.constants'; import { OrgEntityInterface } from './org-entity.interface'; +import { OrgMemberEntityInterface } from './org-member-entity.interface'; export interface OrgEntitiesOptionsInterface { entities: { [ORG_MODULE_ORG_ENTITY_KEY]: TypeOrmExtEntityOptionInterface; + [ORG_MODULE_ORG_MEMBER_ENTITY_KEY]: TypeOrmExtEntityOptionInterface; }; } diff --git a/packages/nestjs-org/src/org.constants.ts b/packages/nestjs-org/src/org.constants.ts index fa0a82c53..9b1482186 100644 --- a/packages/nestjs-org/src/org.constants.ts +++ b/packages/nestjs-org/src/org.constants.ts @@ -4,4 +4,4 @@ export const ORG_MODULE_DEFAULT_SETTINGS_TOKEN = export const ORG_MODULE_OWNER_LOOKUP_SERVICE_TOKEN = 'ORG_MODULE_OWNER_LOOKUP_SERVICE_TOKEN'; export const ORG_MODULE_ORG_ENTITY_KEY = 'org'; -export const MODULE_ORG_MEMBER_ENTITY_KEY = 'orgMember'; +export const ORG_MODULE_ORG_MEMBER_ENTITY_KEY = 'orgMember'; diff --git a/packages/nestjs-org/src/org.controller.e2e-spec.ts b/packages/nestjs-org/src/org.controller.e2e-spec.ts index 420b6332b..53a884416 100644 --- a/packages/nestjs-org/src/org.controller.e2e-spec.ts +++ b/packages/nestjs-org/src/org.controller.e2e-spec.ts @@ -5,15 +5,17 @@ import { getDataSourceToken } from '@nestjs/typeorm'; import { TypeOrmExtModule } from '@concepta/nestjs-typeorm-ext'; import { CrudModule } from '@concepta/nestjs-crud'; import { SeedingSource } from '@concepta/typeorm-seeding'; + import { OrgFactory } from './seeding/org.factory'; import { OrgSeeder } from './seeding/org.seeder'; import { OrgModule } from './org.module'; - import { OrgEntityFixture } from './__fixtures__/org-entity.fixture'; import { OwnerEntityFixture } from './__fixtures__/owner-entity.fixture'; import { OwnerLookupServiceFixture } from './__fixtures__/owner-lookup-service.fixture'; import { OwnerModuleFixture } from './__fixtures__/owner.module.fixture'; import { OwnerFactoryFixture } from './__fixtures__/owner-factory.fixture'; +import { OrgMemberEntityFixture } from './__fixtures__/org-member.entity.fixture'; +import { UserEntityFixture } from './__fixtures__/user-entity.fixture'; describe('OrgController (e2e)', () => { describe('Rest', () => { @@ -27,7 +29,12 @@ describe('OrgController (e2e)', () => { type: 'sqlite', database: ':memory:', synchronize: true, - entities: [OrgEntityFixture, OwnerEntityFixture], + entities: [ + OrgEntityFixture, + OwnerEntityFixture, + OrgMemberEntityFixture, + UserEntityFixture, + ], }), OrgModule.registerAsync({ inject: [OwnerLookupServiceFixture], @@ -38,6 +45,9 @@ describe('OrgController (e2e)', () => { org: { entity: OrgEntityFixture, }, + orgMember: { + entity: OrgMemberEntityFixture, + }, }, }), CrudModule.forRoot({}), diff --git a/packages/nestjs-org/src/org.module.spec.ts b/packages/nestjs-org/src/org.module.spec.ts index 593dac570..c4b3da0f5 100644 --- a/packages/nestjs-org/src/org.module.spec.ts +++ b/packages/nestjs-org/src/org.module.spec.ts @@ -55,6 +55,9 @@ describe('OrgModule', () => { org: { entity: OrgEntityFixture, }, + orgMember: { + entity: OrgMemberEntityFixture, + }, }, }), CrudModule.forRoot({}), diff --git a/packages/nestjs-org/src/services/org-member-lookup.service.ts b/packages/nestjs-org/src/services/org-member-lookup.service.ts index 837ab5129..efdf71c8e 100644 --- a/packages/nestjs-org/src/services/org-member-lookup.service.ts +++ b/packages/nestjs-org/src/services/org-member-lookup.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'; import { InjectDynamicRepository } from '@concepta/nestjs-typeorm-ext'; import { LookupService } from '@concepta/typeorm-common'; -import { MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; +import { ORG_MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; import { OrgMemberLookupServiceInterface } from '../interfaces/org-member-lookup-service.interface'; @@ -16,7 +16,7 @@ export class OrgMemberLookupService implements OrgMemberLookupServiceInterface { constructor( - @InjectDynamicRepository(MODULE_ORG_MEMBER_ENTITY_KEY) + @InjectDynamicRepository(ORG_MODULE_ORG_MEMBER_ENTITY_KEY) repo: Repository, ) { super(repo); diff --git a/packages/nestjs-org/src/services/org-member-mutate.service.ts b/packages/nestjs-org/src/services/org-member-mutate.service.ts index b72785c4d..3bf8831d8 100644 --- a/packages/nestjs-org/src/services/org-member-mutate.service.ts +++ b/packages/nestjs-org/src/services/org-member-mutate.service.ts @@ -6,7 +6,7 @@ import { Type } from '@concepta/ts-core'; import { OrgMemberMutateServiceInterface } from '../interfaces/org-member-mutate-service.interface'; import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; -import { MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; +import { ORG_MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; import { OrgMemberCreatableInterface } from '../interfaces/org-member-creatable.interface'; import { OrgMemberUpdatableInterface } from '../interfaces/org-member-updatable.interface'; @@ -23,7 +23,7 @@ export class OrgMemberMutateService implements OrgMemberMutateServiceInterface { constructor( - @InjectDynamicRepository(MODULE_ORG_MEMBER_ENTITY_KEY) + @InjectDynamicRepository(ORG_MODULE_ORG_MEMBER_ENTITY_KEY) repo: Repository, ) { super(repo); From 56f8a482767894f19765015451279826be0ed34e Mon Sep 17 00:00:00 2001 From: Leonardo Cartaxo Date: Mon, 7 Nov 2022 09:55:56 -0300 Subject: [PATCH 3/8] feat: fixed tests, added invitation org event test, added constraints in invitation --- package.json | 4 +- .../src/__fixtures__/app.module.fixture.ts | 1 - .../invitation.controller.e2e-spec.ts | 112 ++++++++++---- .../src/controllers/invitation.controller.ts | 1 + .../entities/invitation-postgres.entity.ts | 6 +- .../src/entities/invitation-sqlite.entity.ts | 4 + packages/nestjs-org/package.json | 3 +- .../__fixtures__/invitation-accepted.event.ts | 7 + .../__fixtures__/invitation.entity.fixture.ts | 11 ++ .../src/__fixtures__/user-entity.fixture.ts | 4 + .../org-member-service.interface.ts | 14 ++ .../invitation-accepted-listener.spec.ts | 140 ++++++++++++++++++ .../listeners/invitation-accepted-listener.ts | 50 ++----- .../nestjs-org/src/org.controller.e2e-spec.ts | 2 + .../nestjs-org/src/org.module-definition.ts | 5 +- packages/nestjs-org/src/org.module.spec.ts | 2 + packages/nestjs-org/src/org.module.ts | 9 +- .../src/services/org-member.service.ts | 55 +++++++ packages/nestjs-org/tsconfig.json | 3 + packages/nestjs-user/src/index.ts | 3 + packages/ts-common/package.json | 1 + .../interfaces/invitation.interface.ts | 2 + 22 files changed, 361 insertions(+), 78 deletions(-) create mode 100644 packages/nestjs-org/src/__fixtures__/invitation-accepted.event.ts create mode 100644 packages/nestjs-org/src/__fixtures__/invitation.entity.fixture.ts create mode 100644 packages/nestjs-org/src/interfaces/org-member-service.interface.ts create mode 100644 packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts create mode 100644 packages/nestjs-org/src/services/org-member.service.ts diff --git a/package.json b/package.json index 9f3dacd14..12205ede1 100644 --- a/package.json +++ b/package.json @@ -55,14 +55,14 @@ "watch": "yarn build && ./node_modules/.bin/tsc --build --watch", "lint": "eslint \"./*.json\" \"packages/*/src/**/*.{ts,js,json}\" --fix", "test": "jest --testTimeout 30000", - "test:one": "jest --testTimeout 30000 packages/nestjs-org/src/org.module.spec.ts", + "test:one": "jest --testTimeout 30000 packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts", "prepare": "husky install && yarn clean && yarn build", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:ci": "yarn test:cov --ci --reporters=default --reporters=jest-junit", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./jest.config-e2e.json --testTimeout 30000", - "test:e2e:one": "jest --config ./jest.config-e2e.json --testTimeout 30000 packages/nestjs-org/src/org.controller.e2e-spec.ts", + "test:e2e:one": "jest --config ./jest.config-e2e.json --testTimeout 30000 packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts", "test:all": "yarn test && yarn test:e2e", "doc": "rimraf ./documentation && compodoc -p ./tsconfig.doc.json --disablePrivate --disableProtected", "doc:serve": "yarn doc -s", diff --git a/packages/nestjs-invitation/src/__fixtures__/app.module.fixture.ts b/packages/nestjs-invitation/src/__fixtures__/app.module.fixture.ts index 704f26a85..ccf731b06 100644 --- a/packages/nestjs-invitation/src/__fixtures__/app.module.fixture.ts +++ b/packages/nestjs-invitation/src/__fixtures__/app.module.fixture.ts @@ -15,7 +15,6 @@ import { MailerModule, MailerService } from '@nestjs-modules/mailer'; import { InvitationModule } from '../invitation.module'; import { InvitationGetUserEventAsync } from '../events/invitation-get-user.event'; - import { InvitationEntityFixture } from './invitation/entities/invitation.entity.fixture'; import { InvitationAcceptedEventAsync } from '../events/invitation-accepted.event'; import { UserOtpEntityFixture } from './user/entities/user-otp-entity.fixture'; diff --git a/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts b/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts index 1d049661a..951a7eb1f 100644 --- a/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts +++ b/packages/nestjs-invitation/src/controllers/invitation.controller.e2e-spec.ts @@ -5,6 +5,7 @@ import { UserFactory } from '@concepta/nestjs-user/src/seeding'; import { ConfigService, ConfigType } from '@nestjs/config'; import { OtpService } from '@concepta/nestjs-otp'; import { + INVITATION_MODULE_CATEGORY_ORG_KEY, INVITATION_MODULE_CATEGORY_USER_KEY, OtpInterface, UserInterface, @@ -26,13 +27,14 @@ import { InvitationEntityFixture } from '../__fixtures__/invitation/entities/inv import { UserEntityFixture } from '../__fixtures__/user/entities/user-entity.fixture'; describe('InvitationController (e2e)', () => { - const category = INVITATION_MODULE_CATEGORY_USER_KEY; + const userCategory = INVITATION_MODULE_CATEGORY_USER_KEY; + const orgCategory = INVITATION_MODULE_CATEGORY_ORG_KEY; const payload = { moreData: 'foo' }; let app: INestApplication; + let invitationFactory: InvitationFactory; let seedingSource: SeedingSource; let user: UserEntityFixture; - let invitation: InvitationEntityInterface; let otpService: OtpService; let configService: ConfigService; let config: ConfigType; @@ -63,13 +65,12 @@ describe('InvitationController (e2e)', () => { seedingSource, }); - const invitationFactory = new InvitationFactory({ + invitationFactory = new InvitationFactory({ entity: InvitationEntityFixture, seedingSource, }); user = await userFactory.create(); - invitation = await invitationFactory.create({ category, user }); }); afterEach(async () => { @@ -77,19 +78,71 @@ describe('InvitationController (e2e)', () => { return app ? await app.close() : undefined; }); + describe('Type: org', () => { + let invitation: InvitationEntityInterface; + + beforeEach(async () => { + invitation = await invitationFactory.create({ + category: orgCategory, + user, + }); + }); + + it('POST invitation', async () => { + await createInvite(app, { + email: user.email, + category: orgCategory, + payload, + }); + }); + + it('PATCH invitation-acceptance', async () => { + const { code } = invitation; + + const otp = await createOtp(config, otpService, user, orgCategory); + + const { passcode } = otp; + + await supertest(app.getHttpServer()) + .patch(`/invitation-acceptance/${code}`) + .send({ + passcode, + payload: { newPassword: 'hOdv2A2h%' }, + } as InvitationAcceptInviteDto) + .expect(200); + }); + }); + describe('Type: user', () => { + let invitation: InvitationEntityInterface; + + beforeEach(async () => { + invitation = await invitationFactory.create({ + category: userCategory, + user, + }); + }); + it('POST invitation', async () => { - await createInvite({ email: user.email, category, payload }); + await createInvite(app, { + email: user.email, + category: userCategory, + payload, + }); }); it('POST invitation (create new user)', async () => { - await createInvite({ email: 'test@mail.com', category, payload }); + await createInvite(app, { + email: 'test@mail.com', + category: userCategory, + payload, + }); }); it('POST invitation reattempt', async () => { - const invitationDto = await createInvite({ + const invitationDto = await createInvite(app, { email: 'test@mail.com', - category, + category: userCategory, payload, }); @@ -101,7 +154,7 @@ describe('InvitationController (e2e)', () => { it('PATCH invitation-acceptance', async () => { const { code } = invitation; - const otp = await createOtp(config, otpService, user, category); + const otp = await createOtp(config, otpService, user, userCategory); const { passcode } = otp; @@ -117,7 +170,7 @@ describe('InvitationController (e2e)', () => { it('GET invitation-acceptance', async () => { const { code } = invitation; - const otp = await createOtp(config, otpService, user, category); + const otp = await createOtp(config, otpService, user, userCategory); const { passcode } = otp; @@ -129,12 +182,12 @@ describe('InvitationController (e2e)', () => { it('GET invitation', async () => { const invitationCreateDto = { email: user.email, - category, + category: userCategory, payload, } as InvitationCreateDto; - const invite1 = await createInvite(invitationCreateDto); - const invite2 = await createInvite(invitationCreateDto); - const invite3 = await createInvite(invitationCreateDto); + const invite1 = await createInvite(app, invitationCreateDto); + const invite2 = await createInvite(app, invitationCreateDto); + const invite3 = await createInvite(app, invitationCreateDto); const response = await supertest(app.getHttpServer()) .get(`/invitation?s={"email": "${invitationCreateDto.email}"}`) @@ -150,9 +203,9 @@ describe('InvitationController (e2e)', () => { }); it('GET invitation/:id', async () => { - const invitation = await createInvite({ + const invitation = await createInvite(app, { email: user.email, - category, + category: userCategory, payload, }); @@ -166,9 +219,9 @@ describe('InvitationController (e2e)', () => { }); it('DELETE invitation/:id', async () => { - const invitation = await createInvite({ + const invitation = await createInvite(app, { email: user.email, - category, + category: userCategory, payload, }); @@ -180,20 +233,21 @@ describe('InvitationController (e2e)', () => { .get(`/invitation/${invitation.id}`) .expect(404); }); - - const createInvite = async ( - invitationCreateDto: InvitationCreateDto, - ): Promise => { - const response = await supertest(app.getHttpServer()) - .post('/invitation') - .send(invitationCreateDto) - .expect(201); - - return response.body as InvitationDto; - }; }); }); +const createInvite = async ( + app: INestApplication, + invitationCreateDto: InvitationCreateDto, +): Promise => { + const response = await supertest(app.getHttpServer()) + .post('/invitation') + .send(invitationCreateDto) + .expect(201); + + return response.body as InvitationDto; +}; + const createOtp = async ( config: ConfigType, otpService: OtpService, diff --git a/packages/nestjs-invitation/src/controllers/invitation.controller.ts b/packages/nestjs-invitation/src/controllers/invitation.controller.ts index 6899e9d0d..93747b8ce 100644 --- a/packages/nestjs-invitation/src/controllers/invitation.controller.ts +++ b/packages/nestjs-invitation/src/controllers/invitation.controller.ts @@ -103,6 +103,7 @@ export class InvitationController email, category, code: randomUUID(), + constraints: payload, }); if (user !== undefined && invite !== undefined) { diff --git a/packages/nestjs-invitation/src/entities/invitation-postgres.entity.ts b/packages/nestjs-invitation/src/entities/invitation-postgres.entity.ts index 86f5ced2c..7fe856478 100644 --- a/packages/nestjs-invitation/src/entities/invitation-postgres.entity.ts +++ b/packages/nestjs-invitation/src/entities/invitation-postgres.entity.ts @@ -8,8 +8,9 @@ import { import { AuditPostgresEmbed } from '@concepta/typeorm-common'; import { InvitationEntityInterface } from '../interfaces/invitation.entity.interface'; +import { LiteralObject } from '@nestjs/common'; -//TODO check this entity later +// TODO check this entity later export abstract class InvitationPostgresEntity implements InvitationEntityInterface { @@ -31,5 +32,8 @@ export abstract class InvitationPostgresEntity @Column() category!: string; + @Column({ type: 'jsonb' }) + constraints?: LiteralObject; + user!: ReferenceIdInterface; } diff --git a/packages/nestjs-invitation/src/entities/invitation-sqlite.entity.ts b/packages/nestjs-invitation/src/entities/invitation-sqlite.entity.ts index ab404cb78..cbb5ba639 100644 --- a/packages/nestjs-invitation/src/entities/invitation-sqlite.entity.ts +++ b/packages/nestjs-invitation/src/entities/invitation-sqlite.entity.ts @@ -8,6 +8,7 @@ import { import { AuditSqlLiteEmbed } from '@concepta/typeorm-common'; import { InvitationEntityInterface } from '../interfaces/invitation.entity.interface'; +import { LiteralObject } from '@nestjs/common'; //TODO check this entity later export abstract class InvitationSqliteEntity @@ -31,5 +32,8 @@ export abstract class InvitationSqliteEntity @Column() category!: string; + @Column({ type: 'simple-json', nullable: true }) + constraints?: LiteralObject; + user!: ReferenceIdInterface; } diff --git a/packages/nestjs-org/package.json b/packages/nestjs-org/package.json index f81110a26..7a90d5146 100644 --- a/packages/nestjs-org/package.json +++ b/packages/nestjs-org/package.json @@ -16,7 +16,6 @@ "@concepta/nestjs-common": "^4.0.0-alpha.22", "@concepta/nestjs-crud": "^4.0.0-alpha.22", "@concepta/nestjs-event": "^4.0.0-alpha.22", - "@concepta/nestjs-user": "^4.0.0-alpha.22", "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", "@concepta/ts-common": "^4.0.0-alpha.22", "@concepta/ts-core": "^4.0.0-alpha.22", @@ -27,6 +26,8 @@ }, "devDependencies": { "@concepta/typeorm-seeding": "^4.0.0-beta.0", + "@concepta/nestjs-invitation": "^4.0.0-alpha.22", + "@concepta/nestjs-user": "^4.0.0-alpha.22", "@faker-js/faker": "^6.0.0-alpha.6", "@nestjs/testing": "^9.0.0", "@nestjs/typeorm": "^9.0.0", diff --git a/packages/nestjs-org/src/__fixtures__/invitation-accepted.event.ts b/packages/nestjs-org/src/__fixtures__/invitation-accepted.event.ts new file mode 100644 index 000000000..c94838c90 --- /dev/null +++ b/packages/nestjs-org/src/__fixtures__/invitation-accepted.event.ts @@ -0,0 +1,7 @@ +import { EventAsync } from '@concepta/nestjs-event'; +import { InvitationAcceptedEventPayloadInterface } from '@concepta/ts-common'; + +export class InvitationAcceptedEventAsync extends EventAsync< + InvitationAcceptedEventPayloadInterface, + boolean +> {} diff --git a/packages/nestjs-org/src/__fixtures__/invitation.entity.fixture.ts b/packages/nestjs-org/src/__fixtures__/invitation.entity.fixture.ts new file mode 100644 index 000000000..fbe5ba4d6 --- /dev/null +++ b/packages/nestjs-org/src/__fixtures__/invitation.entity.fixture.ts @@ -0,0 +1,11 @@ +import { Entity, ManyToOne } from 'typeorm'; +import { InvitationSqliteEntity } from '@concepta/nestjs-invitation'; +import { UserEntityFixture } from './user-entity.fixture'; + +@Entity() +export class InvitationEntityFixture extends InvitationSqliteEntity { + @ManyToOne(() => UserEntityFixture, (user) => user.invitations, { + nullable: false, + }) + user!: UserEntityFixture; +} diff --git a/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts b/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts index 6e1ef703a..b7b8dadce 100644 --- a/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts +++ b/packages/nestjs-org/src/__fixtures__/user-entity.fixture.ts @@ -2,9 +2,13 @@ import { Entity, OneToMany } from 'typeorm'; import { UserSqliteEntity } from '@concepta/nestjs-user'; import { OrgMemberEntityFixture } from './org-member.entity.fixture'; +import { InvitationEntityFixture } from './invitation.entity.fixture'; @Entity() export class UserEntityFixture extends UserSqliteEntity { @OneToMany(() => OrgMemberEntityFixture, (orgMember) => orgMember.org) orgMembers!: OrgMemberEntityFixture[]; + + @OneToMany(() => InvitationEntityFixture, (invitation) => invitation.user) + invitations?: InvitationEntityFixture[]; } diff --git a/packages/nestjs-org/src/interfaces/org-member-service.interface.ts b/packages/nestjs-org/src/interfaces/org-member-service.interface.ts new file mode 100644 index 000000000..63f510176 --- /dev/null +++ b/packages/nestjs-org/src/interfaces/org-member-service.interface.ts @@ -0,0 +1,14 @@ +import { OrgMemberEntityInterface } from './org-member-entity.interface'; +import { OrgMemberCreatableInterface } from './org-member-creatable.interface'; +import { QueryOptionsInterface } from '@concepta/typeorm-common'; + +export interface OrgMemberServiceInterface { + add( + orgMember: OrgMemberCreatableInterface, + queryOptions?: QueryOptionsInterface, + ): Promise; + remove( + id: string, + queryOptions?: QueryOptionsInterface, + ): Promise; +} diff --git a/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts b/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts new file mode 100644 index 000000000..47fdde10d --- /dev/null +++ b/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts @@ -0,0 +1,140 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import { TypeOrmExtModule } from '@concepta/nestjs-typeorm-ext'; +import { CrudModule } from '@concepta/nestjs-crud'; +import { INVITATION_MODULE_CATEGORY_ORG_KEY } from '@concepta/ts-common'; +import { SeedingSource } from '@concepta/typeorm-seeding'; +import { EventDispatchService, EventModule } from '@concepta/nestjs-event'; +import { UserEntityInterface, UserModule } from '@concepta/nestjs-user'; +import { getDataSourceToken } from '@nestjs/typeorm'; +import { InvitationEntityInterface } from '@concepta/nestjs-invitation/src/interfaces/invitation.entity.interface'; +import { UserFactory } from '@concepta/nestjs-user/src/user.factory'; +import { InvitationFactory } from '@concepta/nestjs-invitation/src/invitation.factory'; + +import { InvitationAcceptedListener } from './invitation-accepted-listener'; +import { OrgEntityFixture } from '../__fixtures__/org-entity.fixture'; +import { OwnerEntityFixture } from '../__fixtures__/owner-entity.fixture'; +import { OrgMemberEntityFixture } from '../__fixtures__/org-member.entity.fixture'; +import { UserEntityFixture } from '../__fixtures__/user-entity.fixture'; +import { OrgModule } from '../org.module'; +import { OwnerLookupServiceFixture } from '../__fixtures__/owner-lookup-service.fixture'; +import { OwnerModuleFixture } from '../__fixtures__/owner.module.fixture'; +import { InvitationAcceptedEventAsync } from '../__fixtures__/invitation-accepted.event'; +import { InvitationEntityFixture } from '../__fixtures__/invitation.entity.fixture'; +import { OrgFactory } from '../seeding/org.factory'; +import { OrgEntityInterface } from '../interfaces/org-entity.interface'; +import { OwnerFactoryFixture } from '../__fixtures__/owner-factory.fixture'; + +describe(InvitationAcceptedListener, () => { + const category = INVITATION_MODULE_CATEGORY_ORG_KEY; + let app: INestApplication; + let eventDispatchService: EventDispatchService; + let seedingSource: SeedingSource; + let testUser: UserEntityInterface; + let testOwner: OwnerEntityFixture; + let testOrg: OrgEntityInterface; + let testInvitation: InvitationEntityInterface; + + beforeEach(async () => { + const testingModule: TestingModule = await Test.createTestingModule({ + imports: [ + EventModule.forRoot({}), + TypeOrmExtModule.forRoot({ + type: 'sqlite', + database: ':memory:', + logging: 'all', + synchronize: true, + entities: [ + OrgEntityFixture, + OwnerEntityFixture, + OrgMemberEntityFixture, + UserEntityFixture, + InvitationEntityFixture, + ], + }), + UserModule.forRoot({ + entities: { + user: { + entity: UserEntityFixture, + }, + }, + }), + OrgModule.forRootAsync({ + inject: [OwnerLookupServiceFixture], + useFactory: (ownerLookupService: OwnerLookupServiceFixture) => ({ + ownerLookupService, + settings: { + invitationRequestEvent: InvitationAcceptedEventAsync, + }, + }), + entities: { + org: { + entity: OrgEntityFixture, + }, + orgMember: { + entity: OrgMemberEntityFixture, + }, + }, + }), + CrudModule.forRoot({}), + OwnerModuleFixture.register(), + ], + }).compile(); + app = testingModule.createNestApplication(); + await app.init(); + + eventDispatchService = + testingModule.get(EventDispatchService); + + seedingSource = new SeedingSource({ + dataSource: testingModule.get(getDataSourceToken()), + }); + + const orgFactory = new OrgFactory({ + entity: OrgEntityFixture, + seedingSource, + }); + + const userFactory = new UserFactory({ + entity: UserEntityFixture, + seedingSource, + }); + const ownerFactory = new OwnerFactoryFixture({ + entity: OwnerEntityFixture, + seedingSource, + }); + + const invitationFactory = new InvitationFactory({ + entity: InvitationEntityFixture, + seedingSource, + }); + + testUser = await userFactory.create(); + testOwner = await ownerFactory.create(); + testOrg = await orgFactory.create({ + owner: testOwner, + }); + testInvitation = await invitationFactory.create({ + user: testUser, + category, + constraints: { orgId: testOrg.id }, + }); + }); + + it('event should be listened', async () => { + const invitationAcceptedEventAsync = new InvitationAcceptedEventAsync({ + ...testInvitation, + data: { + userId: testInvitation.user.id, + }, + }); + + const eventResult = await eventDispatchService.async( + invitationAcceptedEventAsync, + ); + + const result = eventResult.some((it) => it === true); + + expect(result); + }); +}); diff --git a/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts b/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts index 6abeefa98..e1df99028 100644 --- a/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts +++ b/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts @@ -11,13 +11,8 @@ import { Inject, Injectable, OnModuleInit, Optional } from '@nestjs/common'; import { ORG_MODULE_SETTINGS_TOKEN } from '../org.constants'; import { OrgSettingsInterface } from '../interfaces/org-settings.interface'; -import { OrgMemberMutateService } from '../services/org-member-mutate.service'; -import { OrgLookupService } from '../services/org-lookup.service'; import { OrgMemberException } from '../exceptions/org-member.exception'; -import { OrgNotFoundException } from '../exceptions/org-not-found.exception'; -import { UserLookupService } from '@concepta/nestjs-user'; -import { UserNotFoundException } from '@concepta/nestjs-user/dist/exceptions/user-not-found-exception'; -import { OrgMemberLookupService } from '../services/org-member-lookup.service'; +import { OrgMemberService } from '../services/org-member.service'; @Injectable() export class InvitationAcceptedListener @@ -29,10 +24,7 @@ export class InvitationAcceptedListener constructor( @Inject(ORG_MODULE_SETTINGS_TOKEN) private settings: OrgSettingsInterface, - private orgLookupService: OrgLookupService, - private userLookupService: UserLookupService, - private orgMemberLookupService: OrgMemberLookupService, - private orgMemberMutateService: OrgMemberMutateService, + private orgMemberService: OrgMemberService, @Optional() @Inject(EventListenService) private eventListenService?: EventListenService, @@ -54,45 +46,23 @@ export class InvitationAcceptedListener ) { // check only for invitation of type category if (event.payload.category === INVITATION_MODULE_CATEGORY_ORG_KEY) { - const { userId, orgId } = event?.payload.data ?? {}; + const { userId } = event?.payload?.data ?? {}; + const { orgId } = event?.payload?.constraints ?? {}; - if (typeof userId !== 'string' || typeof orgId !== 'string') { + if (typeof userId !== 'string') { throw new OrgMemberException( - 'The invitation accepted event payload received has invalid content. The payload must have the "userId" and "orgId" properties.', + 'The invitation accepted event payload received has invalid content. The payload must have the "userId" property.', ); } - const org = await this.orgLookupService.byId( - orgId, - event.payload?.queryOptions, - ); - - if (!org) { - throw new OrgNotFoundException(); - } - - const user = await this.userLookupService.byId( - userId, - event.payload?.queryOptions, - ); - - if (!user) { - throw new UserNotFoundException(); - } - - const orgMember = await this.orgMemberLookupService.findOne( - { where: { orgId, userId } }, - event.payload?.queryOptions, - ); - - if (orgMember) { + if (!orgId) { throw new OrgMemberException( - `Can't create OrgMember, the the combination of userid: ${userId} and orgId: ${orgId} already exists`, + 'The org of invitation does not have orgId in constraints', ); } - await this.orgMemberMutateService.create( - { orgId, userId }, + await this.orgMemberService.add( + { userId, orgId: orgId as string }, event.payload?.queryOptions, ); diff --git a/packages/nestjs-org/src/org.controller.e2e-spec.ts b/packages/nestjs-org/src/org.controller.e2e-spec.ts index 53a884416..36332c14a 100644 --- a/packages/nestjs-org/src/org.controller.e2e-spec.ts +++ b/packages/nestjs-org/src/org.controller.e2e-spec.ts @@ -16,6 +16,7 @@ import { OwnerModuleFixture } from './__fixtures__/owner.module.fixture'; import { OwnerFactoryFixture } from './__fixtures__/owner-factory.fixture'; import { OrgMemberEntityFixture } from './__fixtures__/org-member.entity.fixture'; import { UserEntityFixture } from './__fixtures__/user-entity.fixture'; +import { InvitationEntityFixture } from './__fixtures__/invitation.entity.fixture'; describe('OrgController (e2e)', () => { describe('Rest', () => { @@ -34,6 +35,7 @@ describe('OrgController (e2e)', () => { OwnerEntityFixture, OrgMemberEntityFixture, UserEntityFixture, + InvitationEntityFixture, ], }), OrgModule.registerAsync({ diff --git a/packages/nestjs-org/src/org.module-definition.ts b/packages/nestjs-org/src/org.module-definition.ts index 052ffdbc4..6f6145f91 100644 --- a/packages/nestjs-org/src/org.module-definition.ts +++ b/packages/nestjs-org/src/org.module-definition.ts @@ -17,20 +17,18 @@ import { ORG_MODULE_OWNER_LOOKUP_SERVICE_TOKEN, ORG_MODULE_ORG_ENTITY_KEY, } from './org.constants'; - import { OrgOptionsInterface } from './interfaces/org-options.interface'; import { OrgOptionsExtrasInterface } from './interfaces/org-options-extras.interface'; import { OrgEntitiesOptionsInterface } from './interfaces/org-entities-options.interface'; import { OrgSettingsInterface } from './interfaces/org-settings.interface'; import { OrgEntityInterface } from './interfaces/org-entity.interface'; import { OrgOwnerLookupServiceInterface } from './interfaces/org-owner-lookup-service.interface'; - import { OrgLookupService } from './services/org-lookup.service'; import { OrgMutateService } from './services/org-mutate.service'; import { OrgCrudService } from './services/org-crud.service'; import { OrgController } from './org.controller'; - import { orgDefaultConfig } from './config/org-default.config'; +import { InvitationAcceptedListener } from './listeners/invitation-accepted-listener'; const RAW_OPTIONS_TOKEN = Symbol('__ORG_MODULE_RAW_OPTIONS_TOKEN__'); @@ -85,6 +83,7 @@ export function createOrgProviders(options: { return [ ...(options.providers ?? []), OrgCrudService, + InvitationAcceptedListener, createOrgSettingsProvider(options.overrides), createOrgOwnerLookupServiceProvider(options.overrides), createOrgLookupServiceProvider(options.overrides), diff --git a/packages/nestjs-org/src/org.module.spec.ts b/packages/nestjs-org/src/org.module.spec.ts index c4b3da0f5..666dd2317 100644 --- a/packages/nestjs-org/src/org.module.spec.ts +++ b/packages/nestjs-org/src/org.module.spec.ts @@ -22,6 +22,7 @@ import { OwnerLookupServiceFixture } from './__fixtures__/owner-lookup-service.f import { OwnerModuleFixture } from './__fixtures__/owner.module.fixture'; import { OrgMemberEntityFixture } from './__fixtures__/org-member.entity.fixture'; import { UserEntityFixture } from './__fixtures__/user-entity.fixture'; +import { InvitationEntityFixture } from './__fixtures__/invitation.entity.fixture'; describe('OrgModule', () => { let orgModule: OrgModule; @@ -44,6 +45,7 @@ describe('OrgModule', () => { OwnerEntityFixture, OrgMemberEntityFixture, UserEntityFixture, + InvitationEntityFixture, ], }), OrgModule.forRootAsync({ diff --git a/packages/nestjs-org/src/org.module.ts b/packages/nestjs-org/src/org.module.ts index e8222400c..b1cc8d974 100644 --- a/packages/nestjs-org/src/org.module.ts +++ b/packages/nestjs-org/src/org.module.ts @@ -15,19 +15,26 @@ import { } from './org.module-definition'; import { OrgMemberMutateService } from './services/org-member-mutate.service'; import { OrgMemberLookupService } from './services/org-member-lookup.service'; +import { OrgMemberService } from './services/org-member.service'; /** * Org Module */ @Module({ providers: [ + OrgMemberService, OrgLookupService, OrgMutateService, OrgCrudService, OrgMemberLookupService, OrgMemberMutateService, ], - exports: [OrgLookupService, OrgMutateService, OrgCrudService], + exports: [ + OrgLookupService, + OrgMutateService, + OrgCrudService, + OrgMemberService, + ], controllers: [OrgController], }) export class OrgModule extends OrgModuleClass { diff --git a/packages/nestjs-org/src/services/org-member.service.ts b/packages/nestjs-org/src/services/org-member.service.ts new file mode 100644 index 000000000..bf7d8f63b --- /dev/null +++ b/packages/nestjs-org/src/services/org-member.service.ts @@ -0,0 +1,55 @@ +import { Repository } from 'typeorm'; +import { Injectable } from '@nestjs/common'; +import { InjectDynamicRepository } from '@concepta/nestjs-typeorm-ext'; +import { BaseService, QueryOptionsInterface } from '@concepta/typeorm-common'; + +import { ORG_MODULE_ORG_MEMBER_ENTITY_KEY } from '../org.constants'; +import { OrgMemberEntityInterface } from '../interfaces/org-member-entity.interface'; +import { OrgMemberServiceInterface } from '../interfaces/org-member-service.interface'; +import { OrgMemberCreatableInterface } from '../interfaces/org-member-creatable.interface'; +import { OrgLookupService } from './org-lookup.service'; +import { OrgMemberLookupService } from './org-member-lookup.service'; +import { OrgMemberMutateService } from './org-member-mutate.service'; +import { OrgMemberException } from '../exceptions/org-member.exception'; + +@Injectable() +export class OrgMemberService + extends BaseService + implements OrgMemberServiceInterface +{ + constructor( + @InjectDynamicRepository(ORG_MODULE_ORG_MEMBER_ENTITY_KEY) + repo: Repository, + private orgLookupService: OrgLookupService, + private orgMemberLookupService: OrgMemberLookupService, + private orgMemberMutateService: OrgMemberMutateService, + ) { + super(repo); + } + + async add( + orgMember: OrgMemberCreatableInterface, + queryOptions?: QueryOptionsInterface, + ): Promise { + const orgMemberFound = await this.orgMemberLookupService.findOne( + { where: orgMember }, + queryOptions, + ); + + if (orgMemberFound) { + const { userId, orgId } = orgMember; + throw new OrgMemberException( + `Can't create OrgMember, the the combination of userid: ${userId} and orgId: ${orgId} already exists`, + ); + } + + return await this.orgMemberMutateService.create(orgMember, queryOptions); + } + + async remove( + id: string, + queryOptions?: QueryOptionsInterface, + ): Promise { + return await this.orgMemberMutateService.remove({ id }, queryOptions); + } +} diff --git a/packages/nestjs-org/tsconfig.json b/packages/nestjs-org/tsconfig.json index 926303f4d..86fb29b06 100644 --- a/packages/nestjs-org/tsconfig.json +++ b/packages/nestjs-org/tsconfig.json @@ -27,6 +27,9 @@ }, { "path": "../nestjs-typeorm-ext" + }, + { + "path": "../nestjs-invitation" } ] } diff --git a/packages/nestjs-user/src/index.ts b/packages/nestjs-user/src/index.ts index c4528dec6..429068a09 100644 --- a/packages/nestjs-user/src/index.ts +++ b/packages/nestjs-user/src/index.ts @@ -13,3 +13,6 @@ export { UserLookupServiceInterface } from './interfaces/user-lookup-service.int export { UserMutateServiceInterface } from './interfaces/user-mutate-service.interface'; export { UserResource } from './user.types'; + +export { UserException } from './exceptions/user-exception'; +export { UserNotFoundException } from './exceptions/user-not-found-exception'; diff --git a/packages/ts-common/package.json b/packages/ts-common/package.json index 439188a05..aba060f51 100644 --- a/packages/ts-common/package.json +++ b/packages/ts-common/package.json @@ -12,6 +12,7 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { + "@concepta/nestjs-common": "^4.0.0-alpha.22", "@concepta/nestjs-event": "^4.0.0-alpha.22", "@concepta/ts-core": "^4.0.0-alpha.22" } diff --git a/packages/ts-common/src/invitation/interfaces/invitation.interface.ts b/packages/ts-common/src/invitation/interfaces/invitation.interface.ts index 074b7a6c7..17ef26a70 100644 --- a/packages/ts-common/src/invitation/interfaces/invitation.interface.ts +++ b/packages/ts-common/src/invitation/interfaces/invitation.interface.ts @@ -1,4 +1,5 @@ import { + LiteralObject, ReferenceActiveInterface, ReferenceAuditInterface, ReferenceIdInterface, @@ -12,4 +13,5 @@ export interface InvitationInterface code: string; category: string; user: ReferenceIdInterface; + constraints?: LiteralObject; } From a6d28b10d7cea3a72d4c5b0bfe4282ba88987931 Mon Sep 17 00:00:00 2001 From: Leonardo Cartaxo Date: Mon, 7 Nov 2022 11:03:39 -0300 Subject: [PATCH 4/8] feat: improved invitation event payload interfaces --- .../src/services/invitation-acceptance.service.ts | 2 +- .../src/listeners/invitation-accepted-listener.ts | 11 +++++++---- .../src/listeners/invitation-accepted-listener.ts | 7 +++++-- .../invitation-accepted-event-payload.interface.ts | 5 +++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts b/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts index 6b1199b55..3c79f5341 100644 --- a/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts +++ b/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts @@ -100,7 +100,7 @@ export class InvitationAcceptanceService extends BaseService { const invitationAcceptedEventAsync = new InvitationAcceptedEventAsync({ - ...invitationDto, + invitation: invitationDto, data: payload, queryOptions, }); diff --git a/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts b/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts index e1df99028..8e7055c89 100644 --- a/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts +++ b/packages/nestjs-org/src/listeners/invitation-accepted-listener.ts @@ -45,9 +45,12 @@ export class InvitationAcceptedListener >, ) { // check only for invitation of type category - if (event.payload.category === INVITATION_MODULE_CATEGORY_ORG_KEY) { + if ( + event?.payload?.invitation?.category === + INVITATION_MODULE_CATEGORY_ORG_KEY + ) { const { userId } = event?.payload?.data ?? {}; - const { orgId } = event?.payload?.constraints ?? {}; + const { orgId } = event?.payload?.invitation?.constraints ?? {}; if (typeof userId !== 'string') { throw new OrgMemberException( @@ -55,14 +58,14 @@ export class InvitationAcceptedListener ); } - if (!orgId) { + if (typeof orgId !== 'string') { throw new OrgMemberException( 'The org of invitation does not have orgId in constraints', ); } await this.orgMemberService.add( - { userId, orgId: orgId as string }, + { userId, orgId }, event.payload?.queryOptions, ); diff --git a/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts b/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts index be0fbe634..988cda419 100644 --- a/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts +++ b/packages/nestjs-user/src/listeners/invitation-accepted-listener.ts @@ -48,8 +48,11 @@ export class InvitationAcceptedListener >, ) { // check only for invitation of type category - if (event.payload.category === INVITATION_MODULE_CATEGORY_USER_KEY) { - const { userId, newPassword } = event?.payload.data ?? {}; + if ( + event?.payload?.invitation?.category === + INVITATION_MODULE_CATEGORY_USER_KEY + ) { + const { userId, newPassword } = event?.payload?.data ?? {}; if (typeof userId !== 'string' || typeof newPassword !== 'string') { throw new UserException( diff --git a/packages/ts-common/src/invitation/interfaces/invitation-accepted-event-payload.interface.ts b/packages/ts-common/src/invitation/interfaces/invitation-accepted-event-payload.interface.ts index a40a5082e..2304dcc2b 100644 --- a/packages/ts-common/src/invitation/interfaces/invitation-accepted-event-payload.interface.ts +++ b/packages/ts-common/src/invitation/interfaces/invitation-accepted-event-payload.interface.ts @@ -2,10 +2,11 @@ import { LiteralObject, ReferenceQueryOptionsInterface, } from '@concepta/ts-core'; + import { InvitationInterface } from './invitation.interface'; -export interface InvitationAcceptedEventPayloadInterface - extends InvitationInterface { +export interface InvitationAcceptedEventPayloadInterface { + invitation: InvitationInterface; data?: LiteralObject; queryOptions?: ReferenceQueryOptionsInterface; } From d7dde7c498013d7b0fe0b4d3296804fc7340234f Mon Sep 17 00:00:00 2001 From: Leonardo Cartaxo Date: Mon, 7 Nov 2022 16:39:02 -0300 Subject: [PATCH 5/8] fix: fiz event validation --- .../src/services/invitation-acceptance.service.ts | 2 +- .../src/listeners/invitation-accepted-listener.spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts b/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts index 3c79f5341..cf2c18888 100644 --- a/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts +++ b/packages/nestjs-invitation/src/services/invitation-acceptance.service.ts @@ -109,7 +109,7 @@ export class InvitationAcceptanceService extends BaseService it === true); + return eventResult.every((it) => it === true); } async sendEmail(email: string): Promise { diff --git a/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts b/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts index 47fdde10d..377fcf620 100644 --- a/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts +++ b/packages/nestjs-org/src/listeners/invitation-accepted-listener.spec.ts @@ -123,7 +123,7 @@ describe(InvitationAcceptedListener, () => { it('event should be listened', async () => { const invitationAcceptedEventAsync = new InvitationAcceptedEventAsync({ - ...testInvitation, + invitation: testInvitation, data: { userId: testInvitation.user.id, }, @@ -133,7 +133,7 @@ describe(InvitationAcceptedListener, () => { invitationAcceptedEventAsync, ); - const result = eventResult.some((it) => it === true); + const result = eventResult.every((it) => it === true); expect(result); }); From af3e722b3e1a76b0fc30727a325548762148c9fe Mon Sep 17 00:00:00 2001 From: Marshall Sorenson Date: Tue, 27 Dec 2022 23:06:29 +0000 Subject: [PATCH 6/8] refactor(nestjs-crud): remove opinionated requirement that dtos must have an `id` property --- .../__fixtures__/photo/dto/photo.dto.fixture.ts | 6 +----- .../util/apply-api-response.decorator.ts | 6 ++++-- .../src/dto/crud-invalid-response.dto.ts | 11 +++++++++++ .../src/dto/crud-response-paginated.dto.ts | 9 ++++----- .../nestjs-crud/src/dto/crud-response.dto.ts | 16 ---------------- packages/nestjs-crud/src/index.ts | 3 +-- .../interceptors/crud-serialize.interceptor.ts | 8 ++++---- .../src/interfaces/crud-controller.interface.ts | 3 +-- .../crud-response-paginated.interface.ts | 2 +- .../src/interfaces/crud-response.interface.ts | 6 ------ .../crud-result-paginated.interface.ts | 2 +- packages/nestjs-org/src/dto/org.dto.ts | 6 +----- .../nestjs-role/src/dto/role-assignment.dto.ts | 6 +----- packages/nestjs-role/src/dto/role.dto.ts | 6 +----- 14 files changed, 31 insertions(+), 59 deletions(-) create mode 100644 packages/nestjs-crud/src/dto/crud-invalid-response.dto.ts delete mode 100644 packages/nestjs-crud/src/dto/crud-response.dto.ts delete mode 100644 packages/nestjs-crud/src/interfaces/crud-response.interface.ts diff --git a/packages/nestjs-crud/src/__fixtures__/photo/dto/photo.dto.fixture.ts b/packages/nestjs-crud/src/__fixtures__/photo/dto/photo.dto.fixture.ts index 7f65884f2..3a935fa61 100644 --- a/packages/nestjs-crud/src/__fixtures__/photo/dto/photo.dto.fixture.ts +++ b/packages/nestjs-crud/src/__fixtures__/photo/dto/photo.dto.fixture.ts @@ -2,14 +2,10 @@ import { Exclude, Expose } from 'class-transformer'; import { IsBoolean, IsNumber, IsString, IsUUID } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; import { ReferenceId } from '@concepta/ts-core'; -import { CrudResponseDto } from '../../../dto/crud-response.dto'; import { PhotoEntityInterfaceFixture } from '../interfaces/photo-entity.interface.fixture'; @Exclude() -export class PhotoDtoFixture - extends CrudResponseDto - implements PhotoEntityInterfaceFixture -{ +export class PhotoDtoFixture implements PhotoEntityInterfaceFixture { @ApiProperty() @Expose() @IsUUID() diff --git a/packages/nestjs-crud/src/decorators/util/apply-api-response.decorator.ts b/packages/nestjs-crud/src/decorators/util/apply-api-response.decorator.ts index 2ae424bd6..cb3313294 100644 --- a/packages/nestjs-crud/src/decorators/util/apply-api-response.decorator.ts +++ b/packages/nestjs-crud/src/decorators/util/apply-api-response.decorator.ts @@ -9,8 +9,8 @@ import { } from '@nestjs/swagger'; import { CrudActions } from '@nestjsx/crud'; import { DecoratorTargetObject } from '../../crud.types'; +import { CrudInvalidResponseDto } from '../../dto/crud-invalid-response.dto'; import { CrudResponsePaginatedDto } from '../../dto/crud-response-paginated.dto'; -import { CrudResponseDto } from '../../dto/crud-response.dto'; import { CrudReflectionService } from '../../services/crud-reflection.service'; /** @@ -50,7 +50,9 @@ export function applyApiResponse( // determine the dto type const dto = - serializeOptions?.type ?? requestOptions.model.type ?? CrudResponseDto; + serializeOptions?.type ?? + requestOptions.model.type ?? + CrudInvalidResponseDto; // determine pagination dto const paginatedDto = diff --git a/packages/nestjs-crud/src/dto/crud-invalid-response.dto.ts b/packages/nestjs-crud/src/dto/crud-invalid-response.dto.ts new file mode 100644 index 000000000..f10c05c77 --- /dev/null +++ b/packages/nestjs-crud/src/dto/crud-invalid-response.dto.ts @@ -0,0 +1,11 @@ +import { Exclude } from 'class-transformer'; +import { InternalServerErrorException } from '@nestjs/common'; + +@Exclude() +export class CrudInvalidResponseDto { + constructor() { + throw new InternalServerErrorException( + 'Fell back to default response DTO, this is a security issue.', + ); + } +} diff --git a/packages/nestjs-crud/src/dto/crud-response-paginated.dto.ts b/packages/nestjs-crud/src/dto/crud-response-paginated.dto.ts index 2c93354e5..a24cf2472 100644 --- a/packages/nestjs-crud/src/dto/crud-response-paginated.dto.ts +++ b/packages/nestjs-crud/src/dto/crud-response-paginated.dto.ts @@ -1,19 +1,18 @@ import { Exclude, Expose, Type } from 'class-transformer'; import { ApiProperty } from '@nestjs/swagger'; -import { ReferenceIdInterface } from '@concepta/ts-core'; import { CrudResponsePaginatedInterface } from '../interfaces/crud-response-paginated.interface'; -import { CrudResponseDto } from './crud-response.dto'; +import { CrudInvalidResponseDto } from './crud-invalid-response.dto'; @Exclude() -export class CrudResponsePaginatedDto +export class CrudResponsePaginatedDto implements CrudResponsePaginatedInterface { @Expose() @ApiProperty({ - type: CrudResponseDto, + type: CrudInvalidResponseDto, description: 'The list of records for current page', }) - @Type(() => CrudResponseDto) + @Type(() => CrudInvalidResponseDto) data: T[] = []; @Expose() diff --git a/packages/nestjs-crud/src/dto/crud-response.dto.ts b/packages/nestjs-crud/src/dto/crud-response.dto.ts deleted file mode 100644 index c5388a152..000000000 --- a/packages/nestjs-crud/src/dto/crud-response.dto.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Exclude, Expose } from 'class-transformer'; -import { ApiProperty } from '@nestjs/swagger'; -import { ReferenceIdInterface } from '@concepta/ts-core'; -import { CrudResponseInterface } from '../interfaces/crud-response.interface'; - -@Exclude() -export class CrudResponseDto - implements CrudResponseInterface -{ - @Expose() - @ApiProperty({ - type: 'number', - description: 'Unique identifier', - }) - id: T['id'] = ''; -} diff --git a/packages/nestjs-crud/src/index.ts b/packages/nestjs-crud/src/index.ts index 0934ae97c..a60d90564 100644 --- a/packages/nestjs-crud/src/index.ts +++ b/packages/nestjs-crud/src/index.ts @@ -4,8 +4,8 @@ export { CrudModule } from './crud.module'; // interfaces export { CrudControllerInterface } from './interfaces/crud-controller.interface'; export { CrudRequestInterface } from './interfaces/crud-request.interface'; -export { CrudResponseInterface } from './interfaces/crud-response.interface'; export { CrudResponsePaginatedInterface } from './interfaces/crud-response-paginated.interface'; +export { CrudCreateManyInterface } from './interfaces/crud-create-many.interface'; // controller decorators export { CrudController } from './decorators/controller/crud-controller.decorator'; @@ -47,6 +47,5 @@ export { CrudQueryHelper } from './util/crud-query.helper'; export { TypeOrmCrudService } from './services/typeorm-crud.service'; // dto -export { CrudResponseDto } from './dto/crud-response.dto'; export { CrudResponsePaginatedDto } from './dto/crud-response-paginated.dto'; export { CrudCreateManyDto } from './dto/crud-create-many.dto'; diff --git a/packages/nestjs-crud/src/interceptors/crud-serialize.interceptor.ts b/packages/nestjs-crud/src/interceptors/crud-serialize.interceptor.ts index ba979f1ab..33c8d5f22 100644 --- a/packages/nestjs-crud/src/interceptors/crud-serialize.interceptor.ts +++ b/packages/nestjs-crud/src/interceptors/crud-serialize.interceptor.ts @@ -15,8 +15,8 @@ import { } from 'class-transformer'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -import { LiteralObject, ReferenceIdInterface } from '@concepta/ts-core'; -import { CrudResponseDto } from '../dto/crud-response.dto'; +import { LiteralObject } from '@concepta/ts-core'; +import { CrudInvalidResponseDto } from '../dto/crud-invalid-response.dto'; import { CrudResponsePaginatedDto } from '../dto/crud-response-paginated.dto'; import { CrudSerializationOptionsInterface } from '../interfaces/crud-serialization-options.interface'; import { CrudResultPaginatedInterface } from '../interfaces/crud-result-paginated.interface'; @@ -25,7 +25,7 @@ import { CrudReflectionService } from '../services/crud-reflection.service'; import { CRUD_MODULE_SETTINGS_TOKEN } from '../crud.constants'; type ResponseType = - | (LiteralObject & CrudResultPaginatedInterface) + | (LiteralObject & CrudResultPaginatedInterface) | Array; export class CrudSerializeInterceptor implements NestInterceptor { @@ -116,7 +116,7 @@ export class CrudSerializeInterceptor implements NestInterceptor { // is the type missing? if (!options?.type) { // yes, set it - options.type = modelOptions.type ?? CrudResponseDto; + options.type = modelOptions.type ?? CrudInvalidResponseDto; } // is the many type missing? diff --git a/packages/nestjs-crud/src/interfaces/crud-controller.interface.ts b/packages/nestjs-crud/src/interfaces/crud-controller.interface.ts index 3462fb97e..cb046a9f7 100644 --- a/packages/nestjs-crud/src/interfaces/crud-controller.interface.ts +++ b/packages/nestjs-crud/src/interfaces/crud-controller.interface.ts @@ -1,12 +1,11 @@ import { DeepPartial } from 'typeorm'; import { CreateManyDto } from '@nestjsx/crud'; -import { ReferenceIdInterface } from '@concepta/ts-core'; import { CrudRequestInterface } from '../interfaces/crud-request.interface'; import { CrudResponsePaginatedInterface } from './crud-response-paginated.interface'; import { AdditionalCrudMethodArgs } from '../crud.types'; export interface CrudControllerInterface< - Entity extends ReferenceIdInterface, + Entity, Creatable extends DeepPartial, Updatable extends DeepPartial, Replaceable extends Creatable = Creatable, diff --git a/packages/nestjs-crud/src/interfaces/crud-response-paginated.interface.ts b/packages/nestjs-crud/src/interfaces/crud-response-paginated.interface.ts index 36bff6167..d65205f73 100644 --- a/packages/nestjs-crud/src/interfaces/crud-response-paginated.interface.ts +++ b/packages/nestjs-crud/src/interfaces/crud-response-paginated.interface.ts @@ -1,4 +1,4 @@ import { GetManyDefaultResponse } from '@nestjsx/crud'; -export interface CrudResponsePaginatedInterface +export interface CrudResponsePaginatedInterface extends GetManyDefaultResponse {} diff --git a/packages/nestjs-crud/src/interfaces/crud-response.interface.ts b/packages/nestjs-crud/src/interfaces/crud-response.interface.ts deleted file mode 100644 index a1903222f..000000000 --- a/packages/nestjs-crud/src/interfaces/crud-response.interface.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ReferenceIdInterface } from '@concepta/ts-core'; -export interface CrudResponseInterface< - T extends ReferenceIdInterface = ReferenceIdInterface, -> { - id: T['id']; -} diff --git a/packages/nestjs-crud/src/interfaces/crud-result-paginated.interface.ts b/packages/nestjs-crud/src/interfaces/crud-result-paginated.interface.ts index 5ff843c0a..7e26e34b7 100644 --- a/packages/nestjs-crud/src/interfaces/crud-result-paginated.interface.ts +++ b/packages/nestjs-crud/src/interfaces/crud-result-paginated.interface.ts @@ -1,6 +1,6 @@ import { CrudResponsePaginatedInterface } from './crud-response-paginated.interface'; -export interface CrudResultPaginatedInterface +export interface CrudResultPaginatedInterface extends CrudResponsePaginatedInterface { __isPaginated?: boolean; } diff --git a/packages/nestjs-org/src/dto/org.dto.ts b/packages/nestjs-org/src/dto/org.dto.ts index 3c7bd3f59..fd91702bf 100644 --- a/packages/nestjs-org/src/dto/org.dto.ts +++ b/packages/nestjs-org/src/dto/org.dto.ts @@ -8,16 +8,12 @@ import { } from '@concepta/ts-core'; import { OrgInterface } from '@concepta/ts-common'; import { AuditDto, ReferenceIdDto } from '@concepta/nestjs-common'; -import { CrudResponseDto } from '@concepta/nestjs-crud'; /** * Org DTO */ @Exclude() -export class OrgDto - extends CrudResponseDto - implements OrgInterface -{ +export class OrgDto implements OrgInterface { /** * Unique id */ diff --git a/packages/nestjs-role/src/dto/role-assignment.dto.ts b/packages/nestjs-role/src/dto/role-assignment.dto.ts index 95fbe2e29..c90512cc4 100644 --- a/packages/nestjs-role/src/dto/role-assignment.dto.ts +++ b/packages/nestjs-role/src/dto/role-assignment.dto.ts @@ -8,16 +8,12 @@ import { } from '@concepta/ts-core'; import { RoleAssignmentInterface } from '@concepta/ts-common'; import { AuditDto, ReferenceIdDto } from '@concepta/nestjs-common'; -import { CrudResponseDto } from '@concepta/nestjs-crud'; /** * Role assignment DTO */ @Exclude() -export class RoleAssignmentDto - extends CrudResponseDto - implements RoleAssignmentInterface -{ +export class RoleAssignmentDto implements RoleAssignmentInterface { /** * Unique id */ diff --git a/packages/nestjs-role/src/dto/role.dto.ts b/packages/nestjs-role/src/dto/role.dto.ts index 5b171a08f..a1be37d94 100644 --- a/packages/nestjs-role/src/dto/role.dto.ts +++ b/packages/nestjs-role/src/dto/role.dto.ts @@ -8,16 +8,12 @@ import { } from '@concepta/ts-core'; import { RoleInterface } from '@concepta/ts-common'; import { AuditDto, ReferenceIdDto } from '@concepta/nestjs-common'; -import { CrudResponseDto } from '@concepta/nestjs-crud'; /** * Role DTO */ @Exclude() -export class RoleDto - extends CrudResponseDto - implements RoleInterface -{ +export class RoleDto implements RoleInterface { /** * Unique id */ From 643cab8ca4879b640b92c973906b774d20a92e9a Mon Sep 17 00:00:00 2001 From: Marshall Sorenson Date: Tue, 27 Dec 2022 23:10:40 +0000 Subject: [PATCH 7/8] v4.0.0-alpha.23 --- lerna.json | 2 +- packages/nestjs-access-control/package.json | 4 +-- packages/nestjs-auth-github/package.json | 22 +++++++-------- packages/nestjs-auth-jwt/package.json | 14 +++++----- packages/nestjs-auth-local/package.json | 16 +++++------ packages/nestjs-auth-recovery/package.json | 20 +++++++------- packages/nestjs-auth-refresh/package.json | 14 +++++----- packages/nestjs-authentication/package.json | 10 +++---- packages/nestjs-common/package.json | 6 ++--- packages/nestjs-core/package.json | 2 +- packages/nestjs-crud/package.json | 10 +++---- packages/nestjs-email/package.json | 8 +++--- packages/nestjs-event/package.json | 6 ++--- packages/nestjs-exception/package.json | 4 +-- packages/nestjs-federated/package.json | 14 +++++----- packages/nestjs-invitation/package.json | 28 +++++++++---------- packages/nestjs-jwt/package.json | 6 ++--- packages/nestjs-logger/package.json | 4 +-- packages/nestjs-org/package.json | 18 ++++++------- packages/nestjs-otp/package.json | 14 +++++----- packages/nestjs-password/package.json | 6 ++--- packages/nestjs-role/package.json | 16 +++++------ packages/nestjs-samples/package.json | 30 ++++++++++----------- packages/nestjs-swagger-ui/package.json | 4 +-- packages/nestjs-typeorm-ext/package.json | 6 ++--- packages/nestjs-user/package.json | 22 +++++++-------- packages/ts-common/package.json | 8 +++--- packages/ts-core/package.json | 2 +- packages/typeorm-common/package.json | 8 +++--- 29 files changed, 162 insertions(+), 162 deletions(-) diff --git a/lerna.json b/lerna.json index f9c432a07..bdcf6c275 100644 --- a/lerna.json +++ b/lerna.json @@ -4,5 +4,5 @@ ], "useWorkspaces": true, "npmClient": "yarn", - "version": "4.0.0-alpha.22" + "version": "4.0.0-alpha.23" } diff --git a/packages/nestjs-access-control/package.json b/packages/nestjs-access-control/package.json index a95b5d15f..25a1dd99f 100644 --- a/packages/nestjs-access-control/package.json +++ b/packages/nestjs-access-control/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-access-control", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Access Control", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,7 +12,7 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-auth-github/package.json b/packages/nestjs-auth-github/package.json index 6ff969f28..9bc04d363 100644 --- a/packages/nestjs-auth-github/package.json +++ b/packages/nestjs-auth-github/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-auth-github", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS GitHub Authentication", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,12 +12,12 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-authentication": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-core": "^4.0.0-alpha.22", - "@concepta/nestjs-federated": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-authentication": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-core": "^4.0.0-alpha.23", + "@concepta/nestjs-federated": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", @@ -26,10 +26,10 @@ "passport-github": "^1.1.0" }, "devDependencies": { - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-jwt": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/nestjs-user": "^4.0.0-alpha.22", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-jwt": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/nestjs-user": "^4.0.0-alpha.23", "@nestjs/testing": "^9.0.0", "@types/passport-github": "^1.1.7", "jest-mock-extended": "^2.0.4" diff --git a/packages/nestjs-auth-jwt/package.json b/packages/nestjs-auth-jwt/package.json index 595dca54b..95bec8bb0 100644 --- a/packages/nestjs-auth-jwt/package.json +++ b/packages/nestjs-auth-jwt/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-auth-jwt", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS JWT Authorization", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,12 +12,12 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-authentication": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-jwt": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-authentication": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-jwt": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-auth-local/package.json b/packages/nestjs-auth-local/package.json index d25c82361..7b403cbd4 100644 --- a/packages/nestjs-auth-local/package.json +++ b/packages/nestjs-auth-local/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-auth-local", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Local Authentication", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,12 +12,12 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-authentication": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-password": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-authentication": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-password": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", @@ -25,7 +25,7 @@ "passport-local": "^1.0.0" }, "devDependencies": { - "@concepta/nestjs-jwt": "^4.0.0-alpha.22", + "@concepta/nestjs-jwt": "^4.0.0-alpha.23", "@nestjs/jwt": "^9.0.0", "@nestjs/testing": "^9.0.0", "@types/passport-local": "^1.0.34", diff --git a/packages/nestjs-auth-recovery/package.json b/packages/nestjs-auth-recovery/package.json index 3ecaae2d9..21752d735 100644 --- a/packages/nestjs-auth-recovery/package.json +++ b/packages/nestjs-auth-recovery/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-auth-recovery", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Auth Recovery", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,21 +12,21 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", "@nestjs/swagger": "^6.0.0" }, "devDependencies": { - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-email": "^4.0.0-alpha.22", - "@concepta/nestjs-otp": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/nestjs-user": "^4.0.0-alpha.22", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-email": "^4.0.0-alpha.23", + "@concepta/nestjs-otp": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/nestjs-user": "^4.0.0-alpha.23", "@concepta/typeorm-seeding": "^4.0.0-beta.0", "@faker-js/faker": "6.0.0-alpha.6", "@nestjs/testing": "^9.0.0", diff --git a/packages/nestjs-auth-refresh/package.json b/packages/nestjs-auth-refresh/package.json index 80b54fb92..0cda05633 100644 --- a/packages/nestjs-auth-refresh/package.json +++ b/packages/nestjs-auth-refresh/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-auth-refresh", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Refresh Authentication", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,12 +12,12 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-authentication": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-jwt": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-authentication": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-jwt": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-authentication/package.json b/packages/nestjs-authentication/package.json index 5c9af3de0..7325e1063 100644 --- a/packages/nestjs-authentication/package.json +++ b/packages/nestjs-authentication/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-authentication", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Authentication", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,10 +12,10 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-jwt": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-jwt": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-common/package.json b/packages/nestjs-common/package.json index a38852177..6061c9f62 100644 --- a/packages/nestjs-common/package.json +++ b/packages/nestjs-common/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-common", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Common", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,8 +12,8 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-core": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-core": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/swagger": "^6.0.0" }, diff --git a/packages/nestjs-core/package.json b/packages/nestjs-core/package.json index 62a19edb5..fc2fee60b 100644 --- a/packages/nestjs-core/package.json +++ b/packages/nestjs-core/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-core", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Core", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/nestjs-crud/package.json b/packages/nestjs-crud/package.json index 0532dfa64..717a2dc8f 100644 --- a/packages/nestjs-crud/package.json +++ b/packages/nestjs-crud/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-crud", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS CRUD", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,9 +12,9 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", @@ -24,7 +24,7 @@ "@nestjsx/crud-typeorm": "^5.0.0-alpha.3" }, "devDependencies": { - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", "@concepta/typeorm-seeding": "^4.0.0-beta.0", "@faker-js/faker": "^6.0.0-alpha.7", "@nestjs/testing": "^9.0.0", diff --git a/packages/nestjs-email/package.json b/packages/nestjs-email/package.json index ccb3d9f48..796e5870c 100644 --- a/packages/nestjs-email/package.json +++ b/packages/nestjs-email/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-email", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NodeJS Email", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,9 +12,9 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0" diff --git a/packages/nestjs-event/package.json b/packages/nestjs-event/package.json index 412baef56..056c2b979 100644 --- a/packages/nestjs-event/package.json +++ b/packages/nestjs-event/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-event", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Events", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,8 +12,8 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-exception/package.json b/packages/nestjs-exception/package.json index be16f6937..7c0d18644 100644 --- a/packages/nestjs-exception/package.json +++ b/packages/nestjs-exception/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-exception", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Exceptions", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,7 +12,7 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/swagger": "^6.0.0" }, diff --git a/packages/nestjs-federated/package.json b/packages/nestjs-federated/package.json index 7c6c1997c..d238bc6bb 100644 --- a/packages/nestjs-federated/package.json +++ b/packages/nestjs-federated/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-federated", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "main": "dist/index.js", "types": "dist/index.d.ts", "license": "BSD-3-Clause", @@ -11,17 +11,17 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/swagger": "^6.0.0" }, "devDependencies": { - "@concepta/nestjs-user": "^4.0.0-alpha.22", + "@concepta/nestjs-user": "^4.0.0-alpha.23", "@nestjs/testing": "^9.0.0", "jest-mock-extended": "^2.0.4" }, diff --git a/packages/nestjs-invitation/package.json b/packages/nestjs-invitation/package.json index dce8a4759..860ccbe05 100644 --- a/packages/nestjs-invitation/package.json +++ b/packages/nestjs-invitation/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-invitation", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Invitation", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,25 +12,25 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-access-control": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-core": "^4.0.0-alpha.22", - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-event": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-access-control": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-core": "^4.0.0-alpha.23", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-event": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", "@nestjs/swagger": "^6.0.0" }, "devDependencies": { - "@concepta/nestjs-email": "^4.0.0-alpha.22", - "@concepta/nestjs-otp": "^4.0.0-alpha.22", - "@concepta/nestjs-password": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/nestjs-user": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-email": "^4.0.0-alpha.23", + "@concepta/nestjs-otp": "^4.0.0-alpha.23", + "@concepta/nestjs-password": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/nestjs-user": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@concepta/typeorm-seeding": "^4.0.0-alpha.3", "@faker-js/faker": "6.0.0-alpha.6", "@nestjs-modules/mailer": "^1.6.1", diff --git a/packages/nestjs-jwt/package.json b/packages/nestjs-jwt/package.json index 726d0c595..f63e4f981 100644 --- a/packages/nestjs-jwt/package.json +++ b/packages/nestjs-jwt/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-jwt", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS JWT Utility", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,8 +12,8 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/jwt": "^9.0.0", diff --git a/packages/nestjs-logger/package.json b/packages/nestjs-logger/package.json index d71e11ab1..ebc58de9c 100644 --- a/packages/nestjs-logger/package.json +++ b/packages/nestjs-logger/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-logger", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Logger", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,7 +12,7 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-org/package.json b/packages/nestjs-org/package.json index 7a90d5146..4fa1ffadb 100644 --- a/packages/nestjs-org/package.json +++ b/packages/nestjs-org/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-org", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS User", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,14 +12,14 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-access-control": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-event": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-access-control": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-event": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/swagger": "^6.0.0" diff --git a/packages/nestjs-otp/package.json b/packages/nestjs-otp/package.json index d6df82edf..5689d1398 100644 --- a/packages/nestjs-otp/package.json +++ b/packages/nestjs-otp/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-otp", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS User", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,12 +12,12 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-core": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-core": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "ms": "^2.1.3" diff --git a/packages/nestjs-password/package.json b/packages/nestjs-password/package.json index 0673365d5..86e79f069 100644 --- a/packages/nestjs-password/package.json +++ b/packages/nestjs-password/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-password", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Password", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,8 +12,8 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", diff --git a/packages/nestjs-role/package.json b/packages/nestjs-role/package.json index f2f365d99..db050a046 100644 --- a/packages/nestjs-role/package.json +++ b/packages/nestjs-role/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-role", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS User", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,13 +12,13 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-access-control": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-access-control": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/swagger": "^6.0.0" diff --git a/packages/nestjs-samples/package.json b/packages/nestjs-samples/package.json index c49301b8e..7c2d0f853 100644 --- a/packages/nestjs-samples/package.json +++ b/packages/nestjs-samples/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-samples", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "main": "dist/index.js", "types": "dist/index.d.ts", "license": "BSD-3-Clause", @@ -12,20 +12,20 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-auth-jwt": "^4.0.0-alpha.22", - "@concepta/nestjs-auth-local": "^4.0.0-alpha.22", - "@concepta/nestjs-auth-refresh": "^4.0.0-alpha.22", - "@concepta/nestjs-authentication": "^4.0.0-alpha.22", - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-email": "^4.0.0-alpha.22", - "@concepta/nestjs-event": "^4.0.0-alpha.22", - "@concepta/nestjs-jwt": "^4.0.0-alpha.22", - "@concepta/nestjs-logger": "^4.0.0-alpha.22", - "@concepta/nestjs-password": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/nestjs-user": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-auth-jwt": "^4.0.0-alpha.23", + "@concepta/nestjs-auth-local": "^4.0.0-alpha.23", + "@concepta/nestjs-auth-refresh": "^4.0.0-alpha.23", + "@concepta/nestjs-authentication": "^4.0.0-alpha.23", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-email": "^4.0.0-alpha.23", + "@concepta/nestjs-event": "^4.0.0-alpha.23", + "@concepta/nestjs-jwt": "^4.0.0-alpha.23", + "@concepta/nestjs-logger": "^4.0.0-alpha.23", + "@concepta/nestjs-password": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/nestjs-user": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/core": "^9.0.0", "@nestjs/platform-express": "^9.0.0", diff --git a/packages/nestjs-swagger-ui/package.json b/packages/nestjs-swagger-ui/package.json index ceb92534d..651c25f3d 100644 --- a/packages/nestjs-swagger-ui/package.json +++ b/packages/nestjs-swagger-ui/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-swagger-ui", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS Swagger UI", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,7 +12,7 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/swagger": "^6.0.0" diff --git a/packages/nestjs-typeorm-ext/package.json b/packages/nestjs-typeorm-ext/package.json index 0dfb6fe9a..9cd855a0a 100644 --- a/packages/nestjs-typeorm-ext/package.json +++ b/packages/nestjs-typeorm-ext/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-typeorm-ext", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS TypeORM Extended", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,8 +12,8 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-core": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/nestjs-core": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/typeorm": "^9.0.0" }, diff --git a/packages/nestjs-user/package.json b/packages/nestjs-user/package.json index 3d34f997c..c61f20f00 100644 --- a/packages/nestjs-user/package.json +++ b/packages/nestjs-user/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/nestjs-user", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets NestJS User", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,16 +12,16 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-access-control": "^4.0.0-alpha.22", - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-core": "^4.0.0-alpha.22", - "@concepta/nestjs-crud": "^4.0.0-alpha.22", - "@concepta/nestjs-event": "^4.0.0-alpha.22", - "@concepta/nestjs-password": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", - "@concepta/ts-common": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22", - "@concepta/typeorm-common": "^4.0.0-alpha.22", + "@concepta/nestjs-access-control": "^4.0.0-alpha.23", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-core": "^4.0.0-alpha.23", + "@concepta/nestjs-crud": "^4.0.0-alpha.23", + "@concepta/nestjs-event": "^4.0.0-alpha.23", + "@concepta/nestjs-password": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", + "@concepta/ts-common": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23", + "@concepta/typeorm-common": "^4.0.0-alpha.23", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/swagger": "^6.0.0" diff --git a/packages/ts-common/package.json b/packages/ts-common/package.json index aba060f51..3e969d70b 100644 --- a/packages/ts-common/package.json +++ b/packages/ts-common/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/ts-common", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets Typescript Common", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,8 +12,8 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-event": "^4.0.0-alpha.22", - "@concepta/ts-core": "^4.0.0-alpha.22" + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-event": "^4.0.0-alpha.23", + "@concepta/ts-core": "^4.0.0-alpha.23" } } diff --git a/packages/ts-core/package.json b/packages/ts-core/package.json index d3e4c3d99..8d2784562 100644 --- a/packages/ts-core/package.json +++ b/packages/ts-core/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/ts-core", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets Typescript Core", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/typeorm-common/package.json b/packages/typeorm-common/package.json index ab3da3c28..857d03b69 100644 --- a/packages/typeorm-common/package.json +++ b/packages/typeorm-common/package.json @@ -1,6 +1,6 @@ { "name": "@concepta/typeorm-common", - "version": "4.0.0-alpha.22", + "version": "4.0.0-alpha.23", "description": "Rockets TypeORM Common", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -12,13 +12,13 @@ "dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}" ], "dependencies": { - "@concepta/ts-core": "^4.0.0-alpha.22", + "@concepta/ts-core": "^4.0.0-alpha.23", "@faker-js/faker": "^6.0.0-alpha.6", "@nestjs/common": "^9.0.0" }, "devDependencies": { - "@concepta/nestjs-common": "^4.0.0-alpha.22", - "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.22", + "@concepta/nestjs-common": "^4.0.0-alpha.23", + "@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.23", "@concepta/typeorm-seeding": "^4.0.0-beta.0", "@faker-js/faker": "6.0.0-alpha.6", "@nestjs/typeorm": "^9.0.0" From a6bc5a48505ccbe13a5d9dbcce4e32cac2cdd4d5 Mon Sep 17 00:00:00 2001 From: Marshall Sorenson Date: Thu, 19 Oct 2023 10:35:21 -0400 Subject: [PATCH 8/8] fix(invitation): get user response does not need username --- .../nestjs-invitation/src/services/invitation-send.service.ts | 2 +- .../interfaces/invitation-get-user-event-response.interface.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/nestjs-invitation/src/services/invitation-send.service.ts b/packages/nestjs-invitation/src/services/invitation-send.service.ts index 143095c3a..0e7443d6c 100644 --- a/packages/nestjs-invitation/src/services/invitation-send.service.ts +++ b/packages/nestjs-invitation/src/services/invitation-send.service.ts @@ -70,7 +70,7 @@ export class InvitationSendService { }), ); - const user = eventResult?.find((it) => it.id && it.username && it.email); + const user = eventResult?.find((it) => it.id && it.email); if (!user) { throw new InvitationUserUndefinedException(); diff --git a/packages/ts-common/src/invitation/interfaces/invitation-get-user-event-response.interface.ts b/packages/ts-common/src/invitation/interfaces/invitation-get-user-event-response.interface.ts index 9e3e47afb..8c8cd4129 100644 --- a/packages/ts-common/src/invitation/interfaces/invitation-get-user-event-response.interface.ts +++ b/packages/ts-common/src/invitation/interfaces/invitation-get-user-event-response.interface.ts @@ -1,10 +1,8 @@ import { ReferenceEmailInterface, ReferenceIdInterface, - ReferenceUsernameInterface, } from '@concepta/ts-core'; export interface InvitationGetUserEventResponseInterface extends ReferenceIdInterface, - ReferenceUsernameInterface, ReferenceEmailInterface {}