Skip to content

Commit

Permalink
Merge pull request #215 from Josuto/code_cleanup
Browse files Browse the repository at this point in the history
Code cleanup
  • Loading branch information
Josuto authored Apr 13, 2024
2 parents 1fa7e15 + e8b3e7e commit 25fd00e
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 85 deletions.
3 changes: 1 addition & 2 deletions examples/nestjs-mongoose-book-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
"mongoose": "^8.2.4",
"monguito": "link:../../",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"typescript-optional": "3.0.0-alpha.3"
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.3.2",
Expand Down
8 changes: 8 additions & 0 deletions examples/nestjs-mongoose-book-manager/src/book.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Delete,
Get,
Inject,
NotFoundException,
Param,
Patch,
Post,
Expand Down Expand Up @@ -41,6 +42,13 @@ export class BookController {
private readonly bookRepository: TransactionalRepository<Book>,
) {}

@Get(':id')
async findById(@Param('id') id: string): Promise<Book> {
return (await this.bookRepository.findById(id)).orElseThrow(
() => new NotFoundException(`Book with ID ${id} not found`),
);
}

@Get()
async findAll(): Promise<Book[]> {
return this.bookRepository.findAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('Given the book manager controller', () => {
description: 'Great book on the Java programming language',
edition: 3,
});
storedPaperBook = await bookRepository.save(paperBookToStore, undefined, {
storedPaperBook = await bookRepository.save(paperBookToStore, {
userId: '1234',
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('Given the book manager controller', () => {
description: 'Great book on the Java programming language',
edition: 2,
});
storedPaperBook = await bookRepository.save(paperBookToStore, undefined, {
storedPaperBook = await bookRepository.save(paperBookToStore, {
userId,
});
});
Expand Down Expand Up @@ -167,8 +167,8 @@ describe('Given the book manager controller', () => {
description: 'Fantastic fantasy audio book',
hostingPlatforms: ['Audible'],
});
await bookRepository.save(paperBookToStore, undefined, { userId });
await bookRepository.save(audioBookToStore, undefined, { userId });
await bookRepository.save(paperBookToStore, { userId });
await bookRepository.save(audioBookToStore, { userId });
});

it('deletes all books', async () => {
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "monguito",
"version": "4.8.0",
"version": "5.0.0",
"description": "MongoDB Abstract Repository implementation for Node.js",
"author": {
"name": "Josu Martinez",
Expand Down Expand Up @@ -70,8 +70,10 @@
"test:e2e": "jest --config examples/nestjs-mongoose-book-manager/test-util/jest-e2e.json",
"prepare": "husky"
},
"peerDependencies": {
"mongoose": ">= 8.0.0"
},
"dependencies": {
"mongoose": "^8.2.4",
"typescript-optional": "3.0.0-alpha.3"
},
"devDependencies": {
Expand All @@ -88,6 +90,7 @@
"lint-staged": "^15.2.2",
"microbundle": "^0.15.1",
"mongodb-memory-server": "^9.1.8",
"mongoose": "^8.2.4",
"prettier": "^3.2.5",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
Expand Down
14 changes: 12 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ import {
SaveOptions,
} from './util/operation-options';
import { AuditableSchema, BaseSchema, extendSchema } from './util/schema';
import { Constructor, TypeData, TypeMap } from './util/type-map';
import { TransactionOptions, runInTransaction } from './util/transaction';
import {
AbsConstructor,
Constructor,
SubtypeData,
SubtypeMap,
SupertypeData,
TypeMap,
} from './util/type-map';

export {
AbsConstructor,
Auditable,
AuditableClass,
AuditableSchema,
Expand All @@ -39,9 +47,11 @@ export {
Repository,
SaveAllOptions,
SaveOptions,
SubtypeData,
SubtypeMap,
SupertypeData,
TransactionOptions,
TransactionalRepository,
TypeData,
TypeMap,
UndefinedConstructorException,
ValidationException,
Expand Down
7 changes: 0 additions & 7 deletions src/mongoose.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,10 @@ export abstract class MongooseRepository<T extends Entity & UpdateQuery<T>>
/** @inheritdoc */
async save<S extends T>(
entity: S | PartialEntityWithId<S>,
userId?: string,
options?: SaveOptions,
): Promise<S> {
if (!entity)
throw new IllegalArgumentException('The given entity must be valid');
if (userId) {
console.warn(
"The 'userId' property is deprecated and will be removed from monguito on the next major version release. Use 'options.userId' instead.",
);
options = { ...options, userId };
}
try {
if (!entity.id) {
return await this.insert(entity as S, options);
Expand Down
2 changes: 1 addition & 1 deletion src/mongoose.transactional-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export abstract class MongooseTransactionalRepository<
await Promise.all(
entities.map(
async (entity) =>
await this.save(entity, undefined, {
await this.save(entity, {
userId: options?.userId,
session,
}),
Expand Down
5 changes: 0 additions & 5 deletions src/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export interface Repository<T extends Entity> {
/**
* Saves (insert or update) an entity.
* @param {S | PartialEntityWithId<S>} entity the entity to save.
* @param {string=} userId (optional) the ID of the user executing the action. DEPRECATED! use 'options.userId' instead
* @param {SaveOptions=} options (optional) save operation options.
* @returns {Promise<S>} the saved entity.
* @throws {IllegalArgumentException} if the given entity is `undefined` or `null` or
Expand All @@ -60,10 +59,6 @@ export interface Repository<T extends Entity> {
*/
save: <S extends T>(
entity: S | PartialEntityWithId<S>,
/**
* @deprecated This property is deprecated. Use 'options.userId' instead.
*/
userId?: string,
options?: SaveOptions,
) => Promise<S>;

Expand Down
34 changes: 18 additions & 16 deletions src/util/type-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type AbsConstructor<T> = abstract new (...args: any) => T;
/**
* Models some domain object subtype data.
*/
export type TypeData<T> = {
export type SubtypeData<T> = {
type: Constructor<T>;
schema: Schema;
};
Expand All @@ -33,7 +33,7 @@ export type SupertypeData<T> = {
* Models a map of domain object subtypes.
*/
export type SubtypeMap<T> = {
[key: string]: TypeData<T extends infer U ? U : never>;
[key: string]: SubtypeData<T extends infer U ? U : never>;
};

/**
Expand All @@ -49,19 +49,19 @@ export type TypeMap<T extends Entity> =
* A `TypeMap` implementation designed to ease map content handling for its clients.
*/
export class TypeMapImpl<T extends Entity> {
readonly types: string[];
readonly default: SupertypeData<T>;
readonly data: TypeData<T>[];
readonly typeNames: string[];
readonly supertypeData: SupertypeData<T>;
readonly subtypeData: SubtypeData<T>[];

constructor(map: TypeMap<T>) {
if (!map.Default) {
throw new IllegalArgumentException(
'The given map must include domain supertype data',
);
}
this.default = map.Default as SupertypeData<T>;
this.types = Object.keys(map).filter((key) => key !== 'Default');
this.data = Object.entries(map).reduce((accumulator, entry) => {
this.supertypeData = map.Default as SupertypeData<T>;
this.typeNames = Object.keys(map).filter((key) => key !== 'Default');
this.subtypeData = Object.entries(map).reduce((accumulator, entry) => {
if (entry[0] !== 'Default') {
// @ts-expect-error - safe instantiation as any non-root map entry refers to some subtype data
accumulator.push(entry[1]);
Expand All @@ -70,24 +70,26 @@ export class TypeMapImpl<T extends Entity> {
}, []);
}

getSubtypeData(type: string): TypeData<T> | undefined {
const index = this.types.indexOf(type);
return index !== -1 ? this.data[index] : undefined;
getSubtypeData(type: string): SubtypeData<T> | undefined {
const index = this.typeNames.indexOf(type);
return index !== -1 ? this.subtypeData[index] : undefined;
}

getSupertypeData(): TypeData<T> | SupertypeData<T> {
return this.default;
getSupertypeData(): SupertypeData<T> {
return this.supertypeData;
}

getSupertypeName(): string {
return this.getSupertypeData().type.name;
}

getSubtypesData(): TypeData<T>[] {
return this.data;
getSubtypesData(): SubtypeData<T>[] {
return this.subtypeData;
}

has(type: string): boolean {
return type === this.getSupertypeName() || this.types.indexOf(type) !== -1;
return (
type === this.getSupertypeName() || this.typeNames.indexOf(type) !== -1
);
}
}
41 changes: 15 additions & 26 deletions test/repository/auditable.book.repository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ describe('Given an instance of auditable book repository and a user ID', () => {
isbn: '9780321601919',
});

const auditableBook = await bookRepository.save(
bookToInsert,
undefined,
{ userId: createdBy },
);
const auditableBook = await bookRepository.save(bookToInsert, {
userId: createdBy,
});
expect(auditableBook.createdAt).toBeDefined();
expect(auditableBook.updatedAt).toBeDefined();
expect(auditableBook.createdBy).toEqual(createdBy);
Expand All @@ -48,11 +46,9 @@ describe('Given an instance of auditable book repository and a user ID', () => {
isbn: '9780321834577',
});

const auditableBook = await bookRepository.save(
bookToInsert,
undefined,
{ userId: createdBy },
);
const auditableBook = await bookRepository.save(bookToInsert, {
userId: createdBy,
});
expect(auditableBook.createdAt).toBeDefined();
expect(auditableBook.updatedAt).toBeDefined();
expect(auditableBook.createdBy).toEqual(createdBy);
Expand All @@ -73,11 +69,9 @@ describe('Given an instance of auditable book repository and a user ID', () => {
'Building and Scaling High Performing Technology Organizations',
isbn: '1942788339',
});
storedAuditableBook = await bookRepository.save(
auditableBook,
undefined,
{ userId: createdBy },
);
storedAuditableBook = await bookRepository.save(auditableBook, {
userId: createdBy,
});
});

describe('that is of supertype AuditableBook', () => {
Expand All @@ -88,11 +82,9 @@ describe('Given an instance of auditable book repository and a user ID', () => {
'A Novel About IT, DevOps, and Helping Your Business Win',
} as AuditableBook;

const auditableBook = await bookRepository.save(
bookToUpdate,
undefined,
{ userId: '5678' },
);
const auditableBook = await bookRepository.save(bookToUpdate, {
userId: '5678',
});

expect(auditableBook.createdAt).toEqual(storedAuditableBook.createdAt);
expect(auditableBook.updatedAt?.getTime()).toBeGreaterThan(
Expand All @@ -117,7 +109,6 @@ describe('Given an instance of auditable book repository and a user ID', () => {

storedAuditablePaperBook = await bookRepository.save(
auditablePaperBook,
undefined,
{ userId: createdBy },
);
});
Expand All @@ -128,11 +119,9 @@ describe('Given an instance of auditable book repository and a user ID', () => {
edition: 4,
} as AuditablePaperBook;

const auditableBook = await bookRepository.save(
bookToUpdate,
undefined,
{ userId: updatedBy },
);
const auditableBook = await bookRepository.save(bookToUpdate, {
userId: updatedBy,
});
expect(auditableBook.createdAt).toEqual(
storedAuditablePaperBook.createdAt,
);
Expand Down
Loading

0 comments on commit 25fd00e

Please sign in to comment.