mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-24 07:39:42 +02:00
Typescript rewrite (#147)
* Updated highlight.js * Update .codexdocsrc.sample remove undefined page for a fresh new install * backend rewritten in TS * test -> TS, .added dockerignore, bug fixed * Removed compiled js files, eslint codex/ts added * fixed jsdocs warning, leaving editor confirmation * use path.resolve for DB paths * db drives updated + fixed User model * redundant cleared + style fixed * explicit type fixing * fixing testing code * added body block type * compiled JS files -> dist, fixed compiling errors * fixed compiling error, re-organized ts source code * updated Dockerfile * fixed link to parent page * up nodejs version * fix package name * fix deps Co-authored-by: nvc8996 <nvc.8996@gmail.com> Co-authored-by: Taly <vitalik7tv@yandex.ru>
This commit is contained in:
parent
059cfb96f9
commit
34514761f5
99 changed files with 3817 additions and 2249 deletions
162
src/backend/models/alias.ts
Normal file
162
src/backend/models/alias.ts
Normal file
|
@ -0,0 +1,162 @@
|
|||
import crypto from '../utils/crypto';
|
||||
import database from '../utils/database/index';
|
||||
|
||||
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
|
||||
*
|
||||
*/
|
||||
export interface AliasData {
|
||||
_id?: string;
|
||||
hash?: string;
|
||||
type?: string;
|
||||
deprecated?: boolean;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
class Alias {
|
||||
public _id?: string;
|
||||
public hash?: string;
|
||||
public type?: string;
|
||||
public deprecated?: boolean;
|
||||
public id?: string;
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @param {AliasData} data - info about alias
|
||||
* @param {string} aliasName - alias of entity
|
||||
*/
|
||||
constructor(data: AliasData = {}, aliasName = '') {
|
||||
if (data === null) {
|
||||
data = {};
|
||||
}
|
||||
if (data._id) {
|
||||
this._id = data._id;
|
||||
}
|
||||
if (aliasName) {
|
||||
this.hash = binaryMD5(aliasName);
|
||||
}
|
||||
this.data = data;
|
||||
}
|
||||
/**
|
||||
* Return Alias types
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
public static get types(): { PAGE: string } {
|
||||
return {
|
||||
PAGE: 'page',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return alias with given alias
|
||||
*
|
||||
* @param {string} aliasName - alias of entity
|
||||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
public static async get(aliasName: string): Promise<Alias> {
|
||||
const hash = binaryMD5(aliasName);
|
||||
let data = await aliasesDb.findOne({
|
||||
hash: hash,
|
||||
deprecated: false,
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
data = await aliasesDb.findOne({ hash: hash });
|
||||
}
|
||||
|
||||
return new Alias(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark alias as deprecated
|
||||
*
|
||||
* @param {string} aliasName - alias of entity
|
||||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
public static async markAsDeprecated(aliasName: string): Promise<Alias> {
|
||||
const alias = await Alias.get(aliasName);
|
||||
|
||||
alias.deprecated = true;
|
||||
|
||||
return alias.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save or update alias data in the database
|
||||
*
|
||||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
public async save(): Promise<Alias> {
|
||||
if (!this._id) {
|
||||
const insertedRow = await aliasesDb.insert(this.data) as { _id: string };
|
||||
|
||||
this._id = insertedRow._id;
|
||||
} else {
|
||||
await aliasesDb.update({ _id: this._id }, this.data);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set AliasData object fields to internal model fields
|
||||
*
|
||||
* @param {AliasData} aliasData - info about alias
|
||||
*/
|
||||
public set data(aliasData: AliasData) {
|
||||
const { id, type, hash, deprecated } = aliasData;
|
||||
|
||||
this.id = id || this.id;
|
||||
this.type = type || this.type;
|
||||
this.hash = hash || this.hash;
|
||||
this.deprecated = deprecated || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return AliasData object
|
||||
*
|
||||
* @returns {AliasData}
|
||||
*/
|
||||
public get data(): AliasData {
|
||||
return {
|
||||
_id: this._id,
|
||||
id: this.id,
|
||||
type: this.type,
|
||||
hash: this.hash,
|
||||
deprecated: this.deprecated,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<Alias>}
|
||||
*/
|
||||
public async destroy(): Promise<Alias> {
|
||||
await aliasesDb.remove({ _id: this._id });
|
||||
|
||||
delete this._id;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export default Alias;
|
177
src/backend/models/file.ts
Normal file
177
src/backend/models/file.ts
Normal file
|
@ -0,0 +1,177 @@
|
|||
import database from '../utils/database/index';
|
||||
|
||||
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
|
||||
* @property {string} path - path to uploaded file
|
||||
* @property {string} mimetype - file MIME type
|
||||
* @property {number} size - size of the file in
|
||||
*/
|
||||
export interface FileData {
|
||||
_id?: string;
|
||||
name?: string;
|
||||
filename?: string;
|
||||
path?: string;
|
||||
mimetype?: 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
|
||||
* @property {string} path - path to uploaded file
|
||||
* @property {string} mimetype - file MIME type
|
||||
* @property {number} size - size of the file in
|
||||
*/
|
||||
class File {
|
||||
public _id?: string;
|
||||
public name?: string;
|
||||
public filename?: string;
|
||||
public path?: string;
|
||||
public mimetype?: string;
|
||||
public size?: number;
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @param {FileData} data - info about file
|
||||
*/
|
||||
constructor(data: FileData = {}) {
|
||||
if (data === null) {
|
||||
data = {};
|
||||
}
|
||||
|
||||
if (data._id) {
|
||||
this._id = data._id;
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
}
|
||||
/**
|
||||
* Find and return model of file with given id
|
||||
*
|
||||
* @param {string} _id - file id
|
||||
* @returns {Promise<File>}
|
||||
*/
|
||||
public static async get(_id: string): Promise<File> {
|
||||
const data: FileData = await filesDb.findOne({ _id });
|
||||
|
||||
return new File(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return model of file with given id
|
||||
*
|
||||
* @param {string} filename - uploaded filename
|
||||
* @returns {Promise<File>}
|
||||
*/
|
||||
public static async getByFilename(filename: string): Promise<File> {
|
||||
const data = await filesDb.findOne({ filename });
|
||||
|
||||
return new File(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all files which match passed query object
|
||||
*
|
||||
* @param {object} query - input query
|
||||
* @returns {Promise<File[]>}
|
||||
*/
|
||||
public static async getAll(query: Record<string, unknown> = {}): Promise<File[]> {
|
||||
const docs = await filesDb.find(query);
|
||||
|
||||
return Promise.all(docs.map(doc => new File(doc)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set FileData object fields to internal model fields
|
||||
*
|
||||
* @param {FileData} fileData - info about file
|
||||
*/
|
||||
public set data(fileData: FileData) {
|
||||
const { name, filename, path, mimetype, size } = fileData;
|
||||
|
||||
this.name = name || this.name;
|
||||
this.filename = filename || this.filename;
|
||||
this.path = path ? this.processPath(path) : this.path;
|
||||
this.mimetype = mimetype || this.mimetype;
|
||||
this.size = size || this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return FileData object
|
||||
*
|
||||
* @returns {FileData}
|
||||
*/
|
||||
public get data(): FileData {
|
||||
return {
|
||||
_id: this._id,
|
||||
name: this.name,
|
||||
filename: this.filename,
|
||||
path: this.path,
|
||||
mimetype: this.mimetype,
|
||||
size: this.size,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Save or update file data in the database
|
||||
*
|
||||
* @returns {Promise<File>}
|
||||
*/
|
||||
public async save(): Promise<File> {
|
||||
if (!this._id) {
|
||||
const insertedRow = await filesDb.insert(this.data) as { _id: string };
|
||||
|
||||
this._id = insertedRow._id;
|
||||
} else {
|
||||
await filesDb.update({ _id: this._id }, this.data);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove file data from the database
|
||||
*
|
||||
* @returns {Promise<File>}
|
||||
*/
|
||||
public async destroy(): Promise<File> {
|
||||
await filesDb.remove({ _id: this._id });
|
||||
|
||||
delete this._id;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return readable file data
|
||||
*
|
||||
* @returns {FileData}
|
||||
*/
|
||||
public toJSON(): FileData {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unnecessary public folder prefix
|
||||
*
|
||||
* @param {string} path - input path to be processed
|
||||
* @returns {string}
|
||||
*/
|
||||
private processPath(path: string): string {
|
||||
return path.replace(/^public/, '');
|
||||
}
|
||||
}
|
||||
|
||||
export default File;
|
246
src/backend/models/page.ts
Normal file
246
src/backend/models/page.ts
Normal file
|
@ -0,0 +1,246 @@
|
|||
import urlify from '../utils/urlify';
|
||||
import database from '../utils/database/index';
|
||||
|
||||
const pagesDb = database['pages'];
|
||||
|
||||
/**
|
||||
* @typedef {object} PageData
|
||||
* @property {string} _id - page id
|
||||
* @property {string} title - page title
|
||||
* @property {string} uri - page uri
|
||||
* @property {*} body - page body
|
||||
* @property {string} parent - id of parent page
|
||||
*/
|
||||
export interface PageData {
|
||||
_id?: string;
|
||||
title?: string;
|
||||
uri?: string;
|
||||
body?: any;
|
||||
parent?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Page
|
||||
* @class Page model
|
||||
*
|
||||
* @property {string} _id - page id
|
||||
* @property {string} title - page title
|
||||
* @property {string} uri - page uri
|
||||
* @property {*} body - page body
|
||||
* @property {string} _parent - id of parent page
|
||||
*/
|
||||
class Page {
|
||||
public _id?: string;
|
||||
public body?: any;
|
||||
public title?: string;
|
||||
public uri?: string;
|
||||
public _parent?: string;
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @param {PageData} data - page's data
|
||||
*/
|
||||
constructor(data: PageData = {}) {
|
||||
if (data === null) {
|
||||
data = {};
|
||||
}
|
||||
|
||||
if (data._id) {
|
||||
this._id = data._id;
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return model of page with given id
|
||||
*
|
||||
* @param {string} _id - page id
|
||||
* @returns {Promise<Page>}
|
||||
*/
|
||||
public static async get(_id: string): Promise<Page> {
|
||||
const data = await pagesDb.findOne({ _id });
|
||||
|
||||
return new Page(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return model of page with given uri
|
||||
*
|
||||
* @param {string} uri - page uri
|
||||
* @returns {Promise<Page>}
|
||||
*/
|
||||
public static async getByUri(uri: string): Promise<Page> {
|
||||
const data = await pagesDb.findOne({ uri });
|
||||
|
||||
return new Page(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all pages which match passed query object
|
||||
*
|
||||
* @param {object} query - input query
|
||||
* @returns {Promise<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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set PageData object fields to internal model fields
|
||||
*
|
||||
* @param {PageData} pageData - page's data
|
||||
*/
|
||||
public set data(pageData: PageData) {
|
||||
const { body, parent, uri } = pageData;
|
||||
|
||||
this.body = body || this.body;
|
||||
this.title = this.extractTitleFromBody();
|
||||
this.uri = uri || '';
|
||||
this._parent = parent || this._parent || '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return PageData object
|
||||
*
|
||||
* @returns {PageData}
|
||||
*/
|
||||
public get data(): PageData {
|
||||
return {
|
||||
_id: this._id,
|
||||
title: this.title,
|
||||
uri: this.uri,
|
||||
body: this.body,
|
||||
parent: this._parent,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Link given page as parent
|
||||
*
|
||||
* @param {Page} parentPage - the page to be set as parent
|
||||
*/
|
||||
public set parent(parentPage: Page) {
|
||||
this._parent = parentPage._id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return parent page model
|
||||
*
|
||||
* @returns {Promise<Page>}
|
||||
*/
|
||||
public async getParent(): Promise<Page> {
|
||||
const data = await pagesDb.findOne({ _id: this._parent });
|
||||
|
||||
return new Page(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return child pages models
|
||||
*
|
||||
* @returns {Promise<Page[]>}
|
||||
*/
|
||||
public get children(): Promise<Page[]> {
|
||||
return pagesDb.find({ parent: this._id })
|
||||
.then(data => {
|
||||
return data.map(page => new Page(page));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Save or update page data in the database
|
||||
*
|
||||
* @returns {Promise<Page>}
|
||||
*/
|
||||
public async save(): Promise<Page> {
|
||||
if (this.uri !== undefined) {
|
||||
this.uri = await this.composeUri(this.uri);
|
||||
}
|
||||
|
||||
if (!this._id) {
|
||||
const insertedRow = await pagesDb.insert(this.data) as { _id: string };
|
||||
|
||||
this._id = insertedRow._id;
|
||||
} else {
|
||||
await pagesDb.update({ _id: this._id }, this.data);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove page data from the database
|
||||
*
|
||||
* @returns {Promise<Page>}
|
||||
*/
|
||||
public async destroy(): Promise<Page> {
|
||||
await pagesDb.remove({ _id: this._id });
|
||||
|
||||
delete this._id;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return readable page data
|
||||
*
|
||||
* @returns {PageData}
|
||||
*/
|
||||
public toJSON(): PageData {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return available uri
|
||||
*
|
||||
* @returns {Promise<string>}
|
||||
* @param uri - input uri to be composed
|
||||
*/
|
||||
private async composeUri(uri: string): Promise<string> {
|
||||
let pageWithSameUriCount = 0;
|
||||
|
||||
if (!this._id) {
|
||||
uri = this.transformTitleToUri();
|
||||
}
|
||||
|
||||
if (uri) {
|
||||
let pageWithSameUri = await Page.getByUri(uri);
|
||||
|
||||
while (pageWithSameUri._id && pageWithSameUri._id !== this._id) {
|
||||
pageWithSameUriCount++;
|
||||
pageWithSameUri = await Page.getByUri(uri + `-${pageWithSameUriCount}`);
|
||||
}
|
||||
}
|
||||
|
||||
return pageWithSameUriCount ? uri + `-${pageWithSameUriCount}` : uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract first header from editor data
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
private extractTitleFromBody(): string {
|
||||
const headerBlock = this.body ? this.body.blocks.find((block: Record<string, unknown>) => block.type === 'header') : '';
|
||||
|
||||
return headerBlock ? headerBlock.data.text : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform title for uri
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
private transformTitleToUri(): string {
|
||||
if (this.title === undefined) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return urlify(this.title);
|
||||
}
|
||||
}
|
||||
|
||||
export default Page;
|
247
src/backend/models/pageOrder.ts
Normal file
247
src/backend/models/pageOrder.ts
Normal file
|
@ -0,0 +1,247 @@
|
|||
import database from '../utils/database/index';
|
||||
|
||||
const db = database['pagesOrder'];
|
||||
|
||||
/**
|
||||
* @typedef {object} PageOrderData
|
||||
* @property {string} _id - row unique id
|
||||
* @property {string} page - page id
|
||||
* @property {Array<string>} order - list of ordered pages
|
||||
*/
|
||||
export interface PageOrderData {
|
||||
_id?: string;
|
||||
page?: string;
|
||||
order?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @class PageOrder
|
||||
* @classdesc PageOrder
|
||||
*
|
||||
* Creates order for Pages with children
|
||||
*/
|
||||
class PageOrder {
|
||||
public _id?: string;
|
||||
public page?: string;
|
||||
private _order?: string[];
|
||||
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @param {PageOrderData} data - info about pageOrder
|
||||
*/
|
||||
constructor(data: PageOrderData = {}) {
|
||||
if (data === null) {
|
||||
data = {};
|
||||
}
|
||||
|
||||
if (data._id) {
|
||||
this._id = data._id;
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current Page's children order
|
||||
*
|
||||
* @param {string} pageId - page's id
|
||||
* @returns {Promise<PageOrder>}
|
||||
*/
|
||||
public static async get(pageId: string): Promise<PageOrder> {
|
||||
const order = await db.findOne({ page: pageId });
|
||||
|
||||
let data: PageOrderData = {};
|
||||
|
||||
if (order === null) {
|
||||
data.page = pageId;
|
||||
} else {
|
||||
data = order;
|
||||
}
|
||||
|
||||
return new PageOrder(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all pages which match passed query object
|
||||
*
|
||||
* @param {object} query - input query
|
||||
* @returns {Promise<PageOrder[]>}
|
||||
*/
|
||||
public static async getAll(query: Record<string, unknown> = {}): Promise<PageOrder[]> {
|
||||
const docs = await db.find(query);
|
||||
|
||||
return Promise.all(docs.map(doc => new PageOrder(doc)));
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor data setter
|
||||
*
|
||||
* @param {PageOrderData} pageOrderData - info about pageOrder
|
||||
*/
|
||||
public set data(pageOrderData: PageOrderData) {
|
||||
this.page = pageOrderData.page || '0';
|
||||
this.order = pageOrderData.order || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Page Children order
|
||||
*
|
||||
* @returns {PageOrderData}
|
||||
*/
|
||||
public get data(): PageOrderData {
|
||||
return {
|
||||
_id: this._id,
|
||||
page: '' + this.page,
|
||||
order: this.order,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes page id to the orders array
|
||||
*
|
||||
* @param {string} pageId - page's id
|
||||
*/
|
||||
public push(pageId: string | number): void {
|
||||
if (typeof pageId === 'string') {
|
||||
if (this.order === undefined) {
|
||||
this.order = [];
|
||||
}
|
||||
this.order.push(pageId);
|
||||
} else {
|
||||
throw new Error('given id is not string');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes page id from orders array
|
||||
*
|
||||
* @param {string} pageId - page's id
|
||||
*/
|
||||
public remove(pageId: string): void {
|
||||
if (this.order === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const found = this.order.indexOf(pageId);
|
||||
|
||||
if (found >= 0) {
|
||||
this.order.splice(found, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
if (this.order === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const found1 = this.order.indexOf(putAbovePageId);
|
||||
const found2 = this.order.indexOf(currentPageId);
|
||||
|
||||
if (found1 === -1 || found2 === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const margin = found1 < found2 ? 1 : 0;
|
||||
|
||||
this.order.splice(found1, 0, currentPageId);
|
||||
this.order.splice(found2 + margin, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns page before passed page with id
|
||||
*
|
||||
* @param {string} pageId - identity of page
|
||||
*/
|
||||
public getPageBefore(pageId: string): string | null {
|
||||
if (this.order === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentPageInOrder = this.order.indexOf(pageId);
|
||||
|
||||
/**
|
||||
* If page not found or first return nothing
|
||||
*/
|
||||
if (currentPageInOrder <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.order[currentPageInOrder - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns page before passed page with id
|
||||
*
|
||||
* @param pageId - identity of page
|
||||
*/
|
||||
public getPageAfter(pageId: string): string | null {
|
||||
if (this.order === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentPageInOrder = this.order.indexOf(pageId);
|
||||
|
||||
/**
|
||||
* If page not found or is last
|
||||
*/
|
||||
if (currentPageInOrder === -1 || currentPageInOrder === this.order.length - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.order[currentPageInOrder + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} order - define new order
|
||||
*/
|
||||
public set order(order: string[]) {
|
||||
this._order = order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ordered list
|
||||
*
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public get order(): string[] {
|
||||
return this._order || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Save or update page data in the database
|
||||
*
|
||||
* @returns {Promise<PageOrder>}
|
||||
*/
|
||||
public async save(): Promise<PageOrder> {
|
||||
if (!this._id) {
|
||||
const insertedRow = await db.insert(this.data) as { _id: string};
|
||||
|
||||
this._id = insertedRow._id;
|
||||
} else {
|
||||
await db.update({ _id: this._id }, this.data);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove page data from the database
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async destroy(): Promise<void> {
|
||||
await db.remove({ _id: this._id });
|
||||
|
||||
delete this._id;
|
||||
}
|
||||
}
|
||||
|
||||
export default PageOrder;
|
40
src/backend/models/user.ts
Normal file
40
src/backend/models/user.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import database from '../utils/database/index';
|
||||
|
||||
const db = database['password'];
|
||||
|
||||
export interface UserData {
|
||||
passHash?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class User
|
||||
* @class User model
|
||||
*
|
||||
* @property {string} passHash - hashed password
|
||||
*/
|
||||
class User {
|
||||
public passHash?: string;
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @param {UserData} userData - user data for construct new object
|
||||
*/
|
||||
constructor(userData: UserData) {
|
||||
this.passHash = userData.passHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return model of user.
|
||||
* User is only one.
|
||||
*
|
||||
* @returns {Promise<User>}
|
||||
*/
|
||||
public static async get(): Promise<User> {
|
||||
const userData: UserData = await db.findOne({});
|
||||
|
||||
return new User(userData);
|
||||
}
|
||||
}
|
||||
|
||||
export default User;
|
Loading…
Add table
Add a link
Reference in a new issue