diff --git a/core/loadConfig.js b/core/loadConfig.js index c753c61..94ad8a7 100644 --- a/core/loadConfig.js +++ b/core/loadConfig.js @@ -13,6 +13,7 @@ import _ from 'underscore'; import { console } from '../lib/Cluster.js'; import SaplingError from '../lib/SaplingError.js'; +import Utils from '../lib/Utils.js'; /** @@ -24,6 +25,7 @@ export async function digest() { let config = {}; const argv = yargs(hideBin(process.argv)).argv; + const utils = new Utils(); /* Default configuration values */ const defaultConfig = { @@ -36,7 +38,7 @@ export async function digest() { hooks: 'hooks.json', permissions: 'permissions.json', extension: 'html', - secret: this.utils.randString(), + secret: utils.randString(), showError: true, strict: false, limit: 100, @@ -54,7 +56,7 @@ export async function digest() { mail: { host: process.env.MAIL_HOST || '', port: process.env.MAIL_PORT || 465, - secure: this.utils.trueBoolean(process.env.MAIL_TLS) || true, + secure: utils.trueBoolean(process.env.MAIL_TLS) || true, auth: { user: process.env.MAIL_USER, pass: process.env.MAIL_PASS, @@ -86,7 +88,7 @@ export async function digest() { const configPath = path.join(this.dir, this.configFile || 'config.json'); /* Load the configuration */ - if (await this.utils.exists(configPath)) { + if (await utils.exists(configPath)) { /* If we have a config file, let's load it */ const file = await fs.readFile(configPath); @@ -122,7 +124,7 @@ export async function digest() { /* Check if there's a separate production config */ const prodConfigPath = path.join(this.dir, (this.configFile && this.configFile.replace('.json', `.${process.env.NODE_ENV}.json`)) || `config.${process.env.NODE_ENV}.json`); - if (await this.utils.exists(prodConfigPath)) { + if (await utils.exists(prodConfigPath)) { /* If we have a config file, let's load it */ const file = await fs.readFile(prodConfigPath); diff --git a/core/loadController.js b/core/loadController.js index 7745052..470f581 100644 --- a/core/loadController.js +++ b/core/loadController.js @@ -8,6 +8,7 @@ import path from 'node:path'; import { console } from '../lib/Cluster.js'; import Templating from '../lib/Templating.js'; +import Utils from '../lib/Utils.js'; /** @@ -18,16 +19,18 @@ import Templating from '../lib/Templating.js'; export async function digest() { let controller = {}; + const utils = new Utils(); + /* Generate a controller from the available views */ if ((this.config.autoRouting === 'on' || this.config.autoRouting === true) && this.config.viewsDir !== null) { const viewsPath = path.join(this.dir, this.config.viewsDir); - if (await this.utils.exists(viewsPath)) { + if (await utils.exists(viewsPath)) { const viewsLstat = await fs.lstat(viewsPath); if (viewsLstat.isDirectory()) { /* Load all views in the views directory */ - const views = await this.utils.getFiles(viewsPath); + const views = await utils.getFiles(viewsPath); /* Go through each view */ for (const view_ of views) { @@ -68,7 +71,7 @@ export async function digest() { const controllerPath = path.join(this.dir, this.config.routes || ''); /* Load the controller file */ - if (await this.utils.exists(controllerPath)) { + if (await utils.exists(controllerPath)) { const controllerLstat = await fs.lstat(controllerPath); if (controllerLstat.isFile()) { diff --git a/core/loadHooks.js b/core/loadHooks.js index 8d0b465..d81e9f0 100644 --- a/core/loadHooks.js +++ b/core/loadHooks.js @@ -9,6 +9,7 @@ import path from 'node:path'; import { console } from '../lib/Cluster.js'; import Response from '../lib/Response.js'; import SaplingError from '../lib/SaplingError.js'; +import Utils from '../lib/Utils.js'; /** @@ -17,13 +18,15 @@ import SaplingError from '../lib/SaplingError.js'; * @returns {object} Hooks */ export async function digest() { + const utils = new Utils(); + /* Location of the hooks file */ const hooksPath = path.join(this.dir, this.config.hooks); const formattedHooks = {}; /* Load the hooks file */ - if (await this.utils.exists(hooksPath)) { + if (await utils.exists(hooksPath)) { /* If we have a hooks file, let's load it */ let file = null; let hooks = {}; diff --git a/core/loadModel.js b/core/loadModel.js index e2498e0..b3bbf12 100644 --- a/core/loadModel.js +++ b/core/loadModel.js @@ -9,6 +9,7 @@ import path from 'node:path'; import { console } from '../lib/Cluster.js'; import SaplingError from '../lib/SaplingError.js'; import Storage from '../lib/Storage.js'; +import Utils from '../lib/Utils.js'; /** @@ -17,12 +18,14 @@ import Storage from '../lib/Storage.js'; * @returns {object} Schema */ export async function digest() { + const utils = new Utils(); + const modelPath = path.join(this.dir, this.config.modelsDir); const schema = {}; let files = {}; /* Load all models in the model directory */ - if (await this.utils.exists(modelPath)) { + if (await utils.exists(modelPath)) { files = await fs.readdir(modelPath); } else { console.warn(`Models directory \`${modelPath}\` does not exist`); diff --git a/lib/Storage.js b/lib/Storage.js index 49adf21..c82cd30 100755 --- a/lib/Storage.js +++ b/lib/Storage.js @@ -16,38 +16,6 @@ import Response from './Response.js'; import Utils from './Utils.js'; -/* Default user structure */ -/* Extensible through a users model */ -const userStructure = { - email: { type: 'String', minlen: 3, email: true, unique: true, required: true, identifiable: true }, - password: { type: 'String', minlen: 3, required: true, access: { r: 'owner', w: 'owner' } }, - _salt: { type: 'String', access: { r: 'owner', w: 'owner' } }, - role: { type: 'String', values: ['admin', 'member'], default: 'member', access: { r: 'anyone', w: 'admin' } }, - _authkey: { type: 'String', access: { r: 'owner', w: 'owner' } }, -}; - - -/* File uploads structure */ -const uploadStructure = { - // URL to the full original file - url: { type: 'String', required: true }, - // Type, one of "image", "document", "archive", "other" - type: { type: 'String', values: ['image', 'video', 'audio', 'document', 'archive', 'font', 'other'], default: 'other' }, - // URL to a Sapling-generated thumbnail - // thumbnail_url: {type: "String"}, - // Filesize of the original in bytes - filesize: { type: 'Number' }, - // File extension as presented - extension: { type: 'String' }, - // Detected mimetype - mimetype: { type: 'String' }, - // Width in pixels for uploads of the "image" type - // width: {type: "Number"}, - // Height in pixels for uploads of the "image" type - // height: {type: "Number"} -}; - - /** * The Storage class */ @@ -58,6 +26,38 @@ export default class Storage { db = null; + /* Default user structure */ + /* Extensible through a users model */ + userStructure = { + email: { type: 'String', minlen: 3, email: true, unique: true, required: true, identifiable: true }, + password: { type: 'String', minlen: 3, required: true, access: { r: 'owner', w: 'owner' } }, + _salt: { type: 'String', access: { r: 'owner', w: 'owner' } }, + role: { type: 'String', values: ['admin', 'member'], default: 'member', access: { r: 'anyone', w: 'admin' } }, + _authkey: { type: 'String', access: { r: 'owner', w: 'owner' } }, + }; + + + /* File uploads structure */ + uploadStructure = { + // URL to the full original file + url: { type: 'String', required: true }, + // Type, one of "image", "document", "archive", "other" + type: { type: 'String', values: ['image', 'video', 'audio', 'document', 'archive', 'font', 'other'], default: 'other' }, + // URL to a Sapling-generated thumbnail + // thumbnail_url: {type: "String"}, + // Filesize of the original in bytes + filesize: { type: 'Number' }, + // File extension as presented + extension: { type: 'String' }, + // Detected mimetype + mimetype: { type: 'String' }, + // Width in pixels for uploads of the "image" type + // width: {type: "Number"}, + // Height in pixels for uploads of the "image" type + // height: {type: "Number"} + }; + + /** * Initialise the Storage class * @@ -72,15 +72,15 @@ export default class Storage { /* Every app with storage needs a users collection */ if ('users' in this.schema) { /* Allow customization of the structure */ - _.defaults(this.schema.users, userStructure); + _.defaults(this.schema.users, this.userStructure); } else { - this.schema.users = userStructure; + this.schema.users = this.userStructure; } /* Create uploads collection if uploads are enabled */ /* Cold override as this cannot be customised by a model */ if (this.app.uploads) { - this.schema.uploads = uploadStructure; + this.schema.uploads = this.uploadStructure; } }