1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-08-03 12:35:23 +02:00

🤩MongoDB support 🤩 (#272)

* implement configuration through YAML

* remove rcparser

* use password from appConfig

* update docker configs

* fix dockerignore

* implement mongodb driver

* update eslint packages

* fix bugs

* refactor code for grouping by parent

* fix yet another bug

* use unique symbol to the EntityId type

* fix more bugs

* implement db converter

* fix bug with parent selector

* fix eslint

* db-converter refactoring

* create cli program for db-converter

* add readme and gitignore

* update development docs

* update development docs and default config

* add docs about converter

* add src/test to docker ignore

* move database code from utils

* improve docs

* eslint fix

* add more docs

* fix docs

* remove env_file from docker-compose

* implement duplicate detection in db-converter

* use published version of the config-loader

* fix bug

* Update DEVELOPMENT.md

Co-authored-by: Ilya Maroz <37909603+ilyamore88@users.noreply.github.com>

* fix bugs

* fix next/prev buttons

* fix more bugs

* fix sorting

Co-authored-by: Ilya Maroz <37909603+ilyamore88@users.noreply.github.com>
This commit is contained in:
Nikita Melnikov 2022-10-03 16:23:59 +04:00 committed by GitHub
parent 13762096c4
commit 55b4b3ee61
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 12614 additions and 665 deletions

View file

@ -1,46 +1,71 @@
import crypto from '../utils/crypto.js';
import database from '../utils/database/index.js';
import database from '../database/index.js';
import { EntityId } from '../database/types.js';
const binaryMD5 = crypto.binaryMD5;
const aliasesDb = database['aliases'];
/**
* @typedef {object} AliasData
* @property {string} _id - alias id
* @property {string} hash - alias binary hash
* @property {string} type - entity type
* @property {boolean} deprecated - indicate if alias deprecated
* @property {string} id - entity id
*
* Describe an alias
*/
export interface AliasData {
_id?: string;
/**
* Alias id
*/
_id?: EntityId;
/**
* Alias binary hash
*/
hash?: string;
/**
* Entity type
*/
type?: string;
/**
* Indicate if alias deprecated
*/
deprecated?: boolean;
id?: string;
/**
* Entity id
*/
id?: EntityId;
}
/**
* @class Alias
* @classdesc Alias model
*
* @property {string} _id - alias id
* @property {string} hash - alias binary hash
* @property {string} type - entity type
* @property {boolean} deprecated - indicate if alias deprecated
* @property {string} id - entity title
* Alias model
*/
class Alias {
public _id?: string;
/**
* Alias id
*/
public _id?: EntityId;
/**
* Alias binary hash
*/
public hash?: string;
/**
* Entity type
*/
public type?: string;
/**
* Indicate if alias deprecated
*/
public deprecated?: boolean;
public id?: string;
/**
* Entity id
*/
public id?: EntityId;
/**
* @class
*
* @param {AliasData} data - info about alias
* @param {string} aliasName - alias of entity
*/
@ -108,7 +133,7 @@ class Alias {
*/
public async save(): Promise<Alias> {
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 {

View file

@ -1,10 +1,10 @@
import database from '../utils/database/index.js';
import database from '../database/index.js';
import { EntityId } from '../database/types.js';
const filesDb = database['files'];
/**
* @typedef {object} FileData
*
* @property {string} _id - file id
* @property {string} name - original file name
* @property {string} filename - name of uploaded file
@ -14,20 +14,18 @@ const filesDb = database['files'];
* @property {number} size - size of the file in
*/
export interface FileData {
_id?: string;
_id?: EntityId;
name?: string;
filename?: string;
path?: string;
mimetype?: string;
url?: string;
size?: number;
[key: string]: string | number | undefined;
}
/**
* @class File
* @class File model
*
* @property {string} _id - file id
* @property {string} name - original file name
* @property {string} filename - name of uploaded file
@ -36,7 +34,7 @@ export interface FileData {
* @property {number} size - size of the file in
*/
class File {
public _id?: string;
public _id?: EntityId;
public name?: string;
public filename?: string;
public path?: string;
@ -46,7 +44,6 @@ class File {
/**
* @class
*
* @param {FileData} data - info about file
*/
constructor(data: FileData = {}) {
@ -136,7 +133,7 @@ class File {
*/
public async save(): Promise<File> {
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 {

View file

@ -1,5 +1,6 @@
import urlify from '../utils/urlify.js';
import database from '../utils/database/index.js';
import database, {isEqualIds} from '../database/index.js';
import { EntityId } from '../database/types.js';
const pagesDb = database['pages'];
@ -12,17 +13,16 @@ const pagesDb = database['pages'];
* @property {string} parent - id of parent page
*/
export interface PageData {
_id?: string;
_id?: EntityId;
title?: string;
uri?: string;
body?: any;
parent?: string;
parent?: EntityId;
}
/**
* @class Page
* @class Page model
*
* @property {string} _id - page id
* @property {string} title - page title
* @property {string} uri - page uri
@ -30,15 +30,14 @@ export interface PageData {
* @property {string} _parent - id of parent page
*/
class Page {
public _id?: string;
public _id?: EntityId;
public body?: any;
public title?: string;
public uri?: string;
public _parent?: string;
public _parent?: EntityId;
/**
* @class
*
* @param {PageData} data - page's data
*/
constructor(data: PageData = {}) {
@ -59,7 +58,7 @@ class Page {
* @param {string} _id - page id
* @returns {Promise<Page>}
*/
public static async get(_id: string): Promise<Page> {
public static async get(_id: EntityId): Promise<Page> {
const data = await pagesDb.findOne({ _id });
return new Page(data);
@ -86,7 +85,7 @@ class Page {
public static async getAll(query: Record<string, unknown> = {}): Promise<Page[]> {
const docs = await pagesDb.find(query);
return Promise.all(docs.map(doc => new Page(doc)));
return docs.map(doc => new Page(doc));
}
/**
@ -100,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;
}
/**
@ -161,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 {
@ -209,7 +208,7 @@ class Page {
if (uri) {
let pageWithSameUri = await Page.getByUri(uri);
while (pageWithSameUri._id && pageWithSameUri._id !== this._id) {
while (pageWithSameUri._id && !isEqualIds(pageWithSameUri._id, this._id)) {
pageWithSameUriCount++;
pageWithSameUri = await Page.getByUri(uri + `-${pageWithSameUriCount}`);
}

View file

@ -1,4 +1,6 @@
import database from '../utils/database/index.js';
import database, { isEntityId, isEqualIds } from '../database/index.js';
import { ObjectId } from 'mongodb';
import { EntityId } from '../database/types.js';
const db = database['pagesOrder'];
@ -9,9 +11,9 @@ const db = database['pagesOrder'];
* @property {Array<string>} order - list of ordered pages
*/
export interface PageOrderData {
_id?: string;
page?: string;
order?: string[];
_id?: EntityId;
page?: EntityId;
order?: EntityId[];
}
/**
@ -21,14 +23,13 @@ export interface PageOrderData {
* Creates order for Pages with children
*/
class PageOrder {
public _id?: string;
public page?: string;
private _order?: string[];
public _id?: EntityId;
public page?: EntityId;
private _order?: EntityId[];
/**
* @class
*
* @param {PageOrderData} data - info about pageOrder
*/
constructor(data: PageOrderData = {}) {
@ -49,7 +50,7 @@ class PageOrder {
* @param {string} pageId - page's id
* @returns {Promise<PageOrder>}
*/
public static async get(pageId: string): Promise<PageOrder> {
public static async get(pageId: EntityId): Promise<PageOrder> {
const order = await db.findOne({ page: pageId });
let data: PageOrderData = {};
@ -103,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 || [];
}
@ -115,7 +116,7 @@ class PageOrder {
public get data(): PageOrderData {
return {
_id: this._id,
page: '' + this.page,
page: this.page,
order: this.order,
};
}
@ -125,8 +126,8 @@ class PageOrder {
*
* @param {string} pageId - page's id
*/
public push(pageId: string | number): void {
if (typeof pageId === 'string') {
public push(pageId: EntityId): void {
if (isEntityId(pageId)) {
if (this.order === undefined) {
this.order = [];
}
@ -141,12 +142,12 @@ class PageOrder {
*
* @param {string} pageId - page's id
*/
public remove(pageId: string): void {
public remove(pageId: EntityId): void {
if (this.order === undefined) {
return;
}
const found = this.order.indexOf(pageId);
const found = this.order.findIndex(order => isEqualIds(order, pageId));
if (found >= 0) {
this.order.splice(found, 1);
@ -156,16 +157,15 @@ class PageOrder {
/**
* @param {string} currentPageId - page's id that changes the order
* @param {string} putAbovePageId - page's id above which we put the target page
*
* @returns {void}
*/
public putAbove(currentPageId: string, putAbovePageId: string): void {
public putAbove(currentPageId: EntityId, putAbovePageId: EntityId): void {
if (this.order === undefined) {
return;
}
const found1 = this.order.indexOf(putAbovePageId);
const found2 = this.order.indexOf(currentPageId);
const found1 = this.order.findIndex(order => isEqualIds(order, putAbovePageId));
const found2 = this.order.findIndex(order => isEqualIds(order, currentPageId));
if (found1 === -1 || found2 === -1) {
return;
@ -182,12 +182,12 @@ class PageOrder {
*
* @param {string} pageId - identity of page
*/
public getSubPageBefore(pageId: string): string | null {
public getSubPageBefore(pageId: EntityId): EntityId | null {
if (this.order === undefined) {
return null;
}
const currentPageInOrder = this.order.indexOf(pageId);
const currentPageInOrder = this.order.findIndex(order => isEqualIds(order, pageId));
/**
* If page not found or first return nothing
@ -204,12 +204,12 @@ class PageOrder {
*
* @param pageId - identity of page
*/
public getSubPageAfter(pageId: string): string | null {
public getSubPageAfter(pageId: EntityId): EntityId | null {
if (this.order === undefined) {
return null;
}
const currentPageInOrder = this.order.indexOf(pageId);
const currentPageInOrder = this.order.findIndex(order => isEqualIds(order, pageId));
/**
* If page not found or is last
@ -224,7 +224,7 @@ class PageOrder {
/**
* @param {string[]} order - define new order
*/
public set order(order: string[]) {
public set order(order: EntityId[]) {
this._order = order;
}
@ -233,7 +233,7 @@ class PageOrder {
*
* @returns {string[]}
*/
public get order(): string[] {
public get order(): EntityId[] {
return this._order || [];
}
@ -244,7 +244,7 @@ class PageOrder {
*/
public async save(): Promise<PageOrder> {
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 {

View file

@ -1,6 +1,8 @@
import Page from './page.js';
import PageOrder from './pageOrder.js';
import NodeCache from 'node-cache';
import { EntityId } from '../database/types.js';
import { isEqualIds } from '../database/index.js';
// Create cache for flat array
const cache = new NodeCache({ stdTTL: 120 });
@ -14,12 +16,12 @@ export interface PagesFlatArrayData {
/**
* Page id
*/
id: string;
id: EntityId;
/**
* Page parent id
*/
parentId?: string;
parentId?: EntityId;
/**
* id of parent with parent id '0'
@ -105,10 +107,10 @@ class PagesFlatArray {
* @param pageId - page id
* @returns {Promise<PagesFlatArrayData | undefined>}
*/
public static async getPageBefore(pageId: string): Promise<PagesFlatArrayData | undefined> {
public static async getPageBefore(pageId: EntityId): Promise<PagesFlatArrayData | undefined> {
const arr = await this.get();
const pageIndex = arr.findIndex( (item) => item.id == pageId);
const pageIndex = arr.findIndex((item) => isEqualIds(item.id, pageId));
// Check if index is not the first
if (pageIndex && pageIndex > 0) {
@ -125,10 +127,10 @@ class PagesFlatArray {
* @param pageId - page id
* @returns {Promise<PagesFlatArrayData | undefined>}
*/
public static async getPageAfter(pageId: string): Promise<PagesFlatArrayData | undefined> {
public static async getPageAfter(pageId: EntityId): Promise<PagesFlatArrayData | undefined> {
const arr = await this.get();
const pageIndex = arr.findIndex( (item) => item.id == pageId );
const pageIndex = arr.findIndex( (item) => isEqualIds(item.id, pageId));
// Check if index is not the last
if (pageIndex < arr.length -1) {
@ -148,11 +150,11 @@ class PagesFlatArray {
* @param orders - all page orders
* @returns {Promise<Array<PagesFlatArrayData>>}
*/
private static getChildrenFlatArray(pageId: string, level: number,
private static getChildrenFlatArray(pageId: EntityId, level: number,
pages: Array<Page>, orders: Array<PageOrder>): Array<PagesFlatArrayData> {
let arr: Array<PagesFlatArrayData> = new Array<PagesFlatArrayData>();
const page = pages.find( item => item._id == pageId );
const page = pages.find(item => isEqualIds(item._id, pageId));
// Add element to child array
if (page) {
@ -166,7 +168,7 @@ class PagesFlatArray {
} );
}
const order = orders.find(item => item.page == pageId);
const order = orders.find(item => isEqualIds(item.page, pageId));
if (order) {
for (const childPageId of order.order) {