From 29e8c7daecf2c77bdfe397cd32800e19b4e34eb6 Mon Sep 17 00:00:00 2001 From: Nikita Melnikov Date: Sun, 2 Oct 2022 13:15:21 +0800 Subject: [PATCH] use unique symbol to the EntityId type --- src/backend/controllers/pages.ts | 2 +- src/backend/controllers/pagesOrder.ts | 2 +- src/backend/models/alias.ts | 2 +- src/backend/models/file.ts | 2 +- src/backend/models/page.ts | 4 ++-- src/backend/models/pageOrder.ts | 10 +++++----- src/backend/routes/api/pages.ts | 12 +++++++----- src/backend/routes/middlewares/pages.ts | 4 ++-- src/backend/routes/pages.ts | 2 +- src/backend/utils/database/index.ts | 6 +++++- src/backend/utils/database/types.ts | 2 +- 11 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/backend/controllers/pages.ts b/src/backend/controllers/pages.ts index cd49266..97df668 100644 --- a/src/backend/controllers/pages.ts +++ b/src/backend/controllers/pages.ts @@ -90,7 +90,7 @@ class Pages { * @param {string} pageId - pageId to exclude from result pages * @returns {Page[]} */ - public static async groupByParent(pageId: EntityId = ''): Promise { + public static async groupByParent(pageId = '' as EntityId): Promise { const rootPageOrder = await PagesOrder.getRootPageOrder(); // get order of the root pages const childPageOrder = await PagesOrder.getChildPageOrder(); // get order of the all other pages diff --git a/src/backend/controllers/pagesOrder.ts b/src/backend/controllers/pagesOrder.ts index 4682b93..4ced89c 100644 --- a/src/backend/controllers/pagesOrder.ts +++ b/src/backend/controllers/pagesOrder.ts @@ -124,7 +124,7 @@ class PagesOrder { * @param {string} parentPageId - parent page's id that contains both two pages * @param {string} putAbovePageId - page's id above which we put the target page */ - public static async update(unordered: string[], currentPageId: EntityId, parentPageId: EntityId, putAbovePageId: EntityId): Promise { + public static async update(unordered: EntityId[], currentPageId: EntityId, parentPageId: EntityId, putAbovePageId: EntityId): Promise { const pageOrder = await PageOrder.get(parentPageId); // Create unique array with ordered and unordered pages id diff --git a/src/backend/models/alias.ts b/src/backend/models/alias.ts index 172bb57..e0643a8 100644 --- a/src/backend/models/alias.ts +++ b/src/backend/models/alias.ts @@ -133,7 +133,7 @@ class Alias { */ public async save(): Promise { if (!this._id) { - const insertedRow = await aliasesDb.insert(this.data) as { _id: string }; + const insertedRow = await aliasesDb.insert(this.data) as { _id: EntityId }; this._id = insertedRow._id; } else { diff --git a/src/backend/models/file.ts b/src/backend/models/file.ts index 579c94d..884ff08 100644 --- a/src/backend/models/file.ts +++ b/src/backend/models/file.ts @@ -133,7 +133,7 @@ class File { */ public async save(): Promise { if (!this._id) { - const insertedRow = await filesDb.insert(this.data) as { _id: string }; + const insertedRow = await filesDb.insert(this.data) as { _id: EntityId }; this._id = insertedRow._id; } else { diff --git a/src/backend/models/page.ts b/src/backend/models/page.ts index ae814c3..9b5055c 100644 --- a/src/backend/models/page.ts +++ b/src/backend/models/page.ts @@ -99,7 +99,7 @@ class Page { this.body = body || this.body; this.title = this.extractTitleFromBody(); this.uri = uri || ''; - this._parent = parent || this._parent || '0'; + this._parent = parent || this._parent || '0' as EntityId; } /** @@ -160,7 +160,7 @@ class Page { } if (!this._id) { - const insertedRow = await pagesDb.insert(this.data) as { _id: string }; + const insertedRow = await pagesDb.insert(this.data) as { _id: EntityId }; this._id = insertedRow._id; } else { diff --git a/src/backend/models/pageOrder.ts b/src/backend/models/pageOrder.ts index 5603378..e99a974 100644 --- a/src/backend/models/pageOrder.ts +++ b/src/backend/models/pageOrder.ts @@ -1,4 +1,4 @@ -import database from '../utils/database/index.js'; +import database, {isEntityId} from '../utils/database/index.js'; import { ObjectId } from 'mongodb'; import { EntityId } from '../utils/database/types.js'; @@ -104,7 +104,7 @@ class PageOrder { * @param {PageOrderData} pageOrderData - info about pageOrder */ public set data(pageOrderData: PageOrderData) { - this.page = pageOrderData.page || '0'; + this.page = pageOrderData.page || '0' as EntityId; this.order = pageOrderData.order || []; } @@ -116,7 +116,7 @@ class PageOrder { public get data(): PageOrderData { return { _id: this._id, - page: '' + this.page, + page: this.page, order: this.order, }; } @@ -127,7 +127,7 @@ class PageOrder { * @param {string} pageId - page's id */ public push(pageId: EntityId): void { - if (typeof pageId === 'string' || pageId instanceof ObjectId) { + if (isEntityId(pageId)) { if (this.order === undefined) { this.order = []; } @@ -244,7 +244,7 @@ class PageOrder { */ public async save(): Promise { if (!this._id) { - const insertedRow = await db.insert(this.data) as { _id: string}; + const insertedRow = await db.insert(this.data) as { _id: EntityId}; this._id = insertedRow._id; } else { diff --git a/src/backend/routes/api/pages.ts b/src/backend/routes/api/pages.ts index 7931cd2..07758e5 100644 --- a/src/backend/routes/api/pages.ts +++ b/src/backend/routes/api/pages.ts @@ -3,7 +3,7 @@ import multerFunc from 'multer'; import Pages from '../../controllers/pages.js'; import PagesOrder from '../../controllers/pagesOrder.js'; import { EntityId } from '../../utils/database/types.js'; -import {toEntityId} from "../../utils/database/index.js"; +import {isEntityId, toEntityId} from "../../utils/database/index.js"; const router = express.Router(); const multer = multerFunc(); @@ -111,10 +111,10 @@ router.post('/page/:id', multer.none(), async (req: Request, res: Response) => { if (putAbovePageId && putAbovePageId !== '0') { const unordered = pages.filter(_page => _page._parent === page._parent).map(_page => _page._id); - const unOrdered: string[] = []; + const unOrdered: EntityId[] = []; unordered.forEach(item => { - if (typeof item === 'string') { + if (isEntityId(item)) { unOrdered.push(item); } }); @@ -202,10 +202,12 @@ router.delete('/page/:id', async (req: Request, res: Response) => { } }; - await deleteRecursively(req.params.id); + const id = toEntityId(req.params.id) + + await deleteRecursively(id); // remove also from parent's order - parentPageOrder.remove(req.params.id); + parentPageOrder.remove(id); await parentPageOrder.save(); res.json({ diff --git a/src/backend/routes/middlewares/pages.ts b/src/backend/routes/middlewares/pages.ts index 4a1311b..222cd84 100644 --- a/src/backend/routes/middlewares/pages.ts +++ b/src/backend/routes/middlewares/pages.ts @@ -17,7 +17,7 @@ import {isEqualIds} from "../../utils/database/index.js"; * @param {number} currentLevel - current level of element * @returns {Page[]} */ -function createMenuTree(parentPageId: string, pages: Page[], pagesOrder: PageOrder[], level = 1, currentLevel = 1): Page[] { +function createMenuTree(parentPageId: EntityId, pages: Page[], pagesOrder: PageOrder[], level = 1, currentLevel = 1): Page[] { const childrenOrder = pagesOrder.find(order => isEqualIds(order.data.page, parentPageId)); /** @@ -66,7 +66,7 @@ export default asyncMiddleware(async (req: Request, res: Response, next: NextFun * * @type {string} */ - const parentIdOfRootPages = '0'; + const parentIdOfRootPages = '0' as EntityId; try { const pages = await Pages.getAllPages(); diff --git a/src/backend/routes/pages.ts b/src/backend/routes/pages.ts index e9c09b0..18e02d2 100644 --- a/src/backend/routes/pages.ts +++ b/src/backend/routes/pages.ts @@ -57,7 +57,7 @@ router.get('/page/edit/:id', verifyToken, allowEdit, async (req: Request, res: R * View page */ router.get('/page/:id', verifyToken, async (req: Request, res: Response, next: NextFunction) => { - const pageId = req.params.id; + const pageId = toEntityId(req.params.id); try { const page = await Pages.get(pageId); diff --git a/src/backend/utils/database/index.ts b/src/backend/utils/database/index.ts index 63394b9..f80ef43 100644 --- a/src/backend/utils/database/index.ts +++ b/src/backend/utils/database/index.ts @@ -15,13 +15,17 @@ const Database = appConfig.database.driver === 'mongodb' ? MongoDatabaseDriver : * @param id */ export function toEntityId(id: string): EntityId { - return appConfig.database.driver === 'mongodb' ? new ObjectId(id) : id; + return (appConfig.database.driver === 'mongodb' ? new ObjectId(id) : id) as EntityId; } export function isEqualIds(id1?: EntityId, id2?: EntityId): boolean { return id1?.toString() === id2?.toString(); } +export function isEntityId(id?: EntityId): id is EntityId { + return typeof id === 'string' || id instanceof ObjectId; +} + export default { pages: new Database('pages'), aliases: new Database('aliases'), diff --git a/src/backend/utils/database/types.ts b/src/backend/utils/database/types.ts index f26da5a..5b3d618 100644 --- a/src/backend/utils/database/types.ts +++ b/src/backend/utils/database/types.ts @@ -8,7 +8,7 @@ export interface DatabaseDriver { remove(query: Record, options: Options): Promise } -export type EntityId = string | ObjectId; +export type EntityId = (string | ObjectId) & {readonly id: unique symbol}; /** * @typedef Options - optional params