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:
parent
13762096c4
commit
55b4b3ee61
72 changed files with 12614 additions and 665 deletions
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue