From f6fa3eedf443161992dd761b034ba8daeb922b7a Mon Sep 17 00:00:00 2001 From: groenroos Date: Sun, 20 Mar 2022 16:58:39 +0000 Subject: [PATCH 1/2] #432: Convert to Promise-based fs methods --- core/loadConfig.js | 14 ++-- core/loadController.js | 104 ++++++++++++++++-------------- core/loadHooks.js | 6 +- core/loadModel.js | 12 ++-- core/loadPermissions.js | 8 +-- drivers/render/Html.js | 4 +- index.js | 12 ++-- lib/Utils.js | 24 +++++-- test/core/loadConfig.test.js | 68 +++++++++---------- test/core/loadPermissions.test.js | 26 ++++---- test/lib/Utils.test.js | 16 ++--- 11 files changed, 160 insertions(+), 134 deletions(-) diff --git a/core/loadConfig.js b/core/loadConfig.js index f81687d..6594678 100644 --- a/core/loadConfig.js +++ b/core/loadConfig.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import process from 'node:process'; import yargs from 'yargs'; @@ -20,7 +20,7 @@ import SaplingError from '../lib/SaplingError.js'; * * @returns {object} Config */ -export function digest() { +export async function digest() { let config = {}; const argv = yargs(hideBin(process.argv)).argv; @@ -74,9 +74,9 @@ export function digest() { const configPath = path.join(this.dir, this.configFile || 'config.json'); /* Load the configuration */ - if (fs.existsSync(configPath)) { + if (await this.utils.exists(configPath)) { /* If we have a config file, let's load it */ - const file = fs.readFileSync(configPath); + const file = await fs.readFile(configPath); /* Parse and merge the config, or throw an error if it's malformed */ try { @@ -110,9 +110,9 @@ export 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 (fs.existsSync(prodConfigPath)) { + if (await this.utils.exists(prodConfigPath)) { /* If we have a config file, let's load it */ - const file = fs.readFileSync(prodConfigPath); + const file = await fs.readFile(prodConfigPath); config = {}; Object.assign(config, defaultConfig); @@ -143,7 +143,7 @@ export function digest() { */ export default async function loadConfig(next) { /* Digest config */ - this.config = digest.call(this); + this.config = await digest.call(this); console.log('CONFIG', this.config); /* Set the app name */ diff --git a/core/loadController.js b/core/loadController.js index ceecc3b..10626e4 100644 --- a/core/loadController.js +++ b/core/loadController.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; @@ -15,47 +15,51 @@ import Templating from '../lib/Templating.js'; * * @returns {object} Controller */ -export function digest() { +export async function digest() { let controller = {}; /* 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 (fs.existsSync(viewsPath) && fs.lstatSync(viewsPath).isDirectory()) { - /* Load all views in the views directory */ - const views = this.utils.getFiles(viewsPath); + if (await this.utils.exists(viewsPath)) { + const viewsLstat = await fs.lstat(viewsPath); - /* Go through each view */ - for (const view_ of views) { - const segments = path.relative(this.dir, view_).split('/'); + if (viewsLstat.isDirectory()) { + /* Load all views in the views directory */ + const views = await this.utils.getFiles(viewsPath); - /* Filter out the views where any segment begins with _ */ - const protectedSegments = segments.filter(item => { - const re = /^_/; - return re.test(item); - }); + /* Go through each view */ + for (const view_ of views) { + const segments = path.relative(this.dir, view_).split('/'); - if (protectedSegments.length > 0) { - continue; - } + /* Filter out the views where any segment begins with _ */ + const protectedSegments = segments.filter(item => { + const re = /^_/; + return re.test(item); + }); - /* Filter out any files that do not use the correct file extension */ - if (this.config.extension !== null && view_.split('.').slice(-1)[0] !== this.config.extension) { - continue; - } + if (protectedSegments.length > 0) { + continue; + } - /* Filter out filesystem bits */ - const view = view_.replace(path.resolve(this.dir, this.config.viewsDir), '').replace(`.${this.config.extension}`, ''); - let route = view.replace('/index', ''); + /* Filter out any files that do not use the correct file extension */ + if (this.config.extension !== null && view_.split('.').slice(-1)[0] !== this.config.extension) { + continue; + } - /* Make sure root index is a slash and not an empty key */ - if (route === '') { - route = '/'; - } + /* Filter out filesystem bits */ + const view = view_.replace(path.resolve(this.dir, this.config.viewsDir), '').replace(`.${this.config.extension}`, ''); + let route = view.replace('/index', ''); + + /* Make sure root index is a slash and not an empty key */ + if (route === '') { + route = '/'; + } - /* Create an automatic GET route for a given view */ - controller[route] = view.replace(/^\/+/g, ''); + /* Create an automatic GET route for a given view */ + controller[route] = view.replace(/^\/+/g, ''); + } } } } @@ -64,26 +68,30 @@ export function digest() { const controllerPath = path.join(this.dir, this.config.routes || ''); /* Load the controller file */ - if (fs.existsSync(controllerPath) && fs.lstatSync(controllerPath).isFile()) { - /* Parse and merge the controller, or throw an error if it's malformed */ - try { - /* Load the controller file */ - const file = fs.readFileSync(controllerPath); - const routes = JSON.parse(file.toString()); - - /* Remove file extension */ - for (const route of Object.keys(routes)) { - routes[route] = routes[route].split('.').slice(0, -1).join('.'); - } + if (await this.utils.exists(controllerPath)) { + const controllerLstat = await fs.lstat(controllerPath); + + if (controllerLstat.isFile()) { + /* Parse and merge the controller, or throw an error if it's malformed */ + try { + /* Load the controller file */ + const file = await fs.readFile(controllerPath); + const routes = JSON.parse(file.toString()); + + /* Remove file extension */ + for (const route of Object.keys(routes)) { + routes[route] = routes[route].split('.').slice(0, -1).join('.'); + } - /* Merge routes if autorouting, replace routes if not */ - if (this.config.autoRouting === 'on' || this.config.autoRouting === true) { - Object.assign(controller, routes); - } else { - controller = routes; + /* Merge routes if autorouting, replace routes if not */ + if (this.config.autoRouting === 'on' || this.config.autoRouting === true) { + Object.assign(controller, routes); + } else { + controller = routes; + } + } catch (error) { + console.error(`Controller at path: \`${controllerPath}\` could not be loaded.`, error); } - } catch (error) { - console.error(`Controller at path: \`${controllerPath}\` could not be loaded.`, error); } } @@ -102,7 +110,7 @@ export default async function loadController(next) { await this.templating.importDriver(); /* Digest controller */ - this.controller = digest.call(this, this.config); + this.controller = await digest.call(this, this.config); console.log('CONTROLLER', this.controller); if (next) { diff --git a/core/loadHooks.js b/core/loadHooks.js index 5cd7344..b1981c2 100644 --- a/core/loadHooks.js +++ b/core/loadHooks.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; @@ -23,14 +23,14 @@ export async function digest() { const formattedHooks = {}; /* Load the hooks file */ - if (fs.existsSync(hooksPath)) { + if (await this.utils.exists(hooksPath)) { /* If we have a hooks file, let's load it */ let file = null; let hooks = {}; /* Read the hooks file, or throw an error if it can't be done */ try { - file = fs.readFileSync(hooksPath); + file = await fs.readFile(hooksPath); } catch { throw new SaplingError(`Hooks at ${hooksPath} could not be read.`); } diff --git a/core/loadModel.js b/core/loadModel.js index 2a7655f..9527c3d 100644 --- a/core/loadModel.js +++ b/core/loadModel.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; @@ -16,14 +16,14 @@ import Storage from '../lib/Storage.js'; * * @returns {object} Schema */ -export function digest() { +export async function digest() { const modelPath = path.join(this.dir, this.config.modelsDir); const schema = {}; let files = {}; /* Load all models in the model directory */ - if (fs.existsSync(modelPath)) { - files = fs.readdirSync(modelPath); + if (await this.utils.exists(modelPath)) { + files = await fs.readdir(modelPath); } else { console.warn(`Models directory \`${modelPath}\` does not exist`); } @@ -38,7 +38,7 @@ export function digest() { continue; } - const model = fs.readFileSync(path.join(modelPath, file)); + const model = await fs.readFile(path.join(modelPath, file)); /* Read the model JSON into the schema */ try { @@ -80,7 +80,7 @@ export function digest() { */ export default async function loadModel(next) { /* Create a storage instance based on the models */ - this.storage = new Storage(this, digest.call(this)); + this.storage = new Storage(this, await digest.call(this)); if (next) { next(); diff --git a/core/loadPermissions.js b/core/loadPermissions.js index c31c452..eb559b7 100644 --- a/core/loadPermissions.js +++ b/core/loadPermissions.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; @@ -16,14 +16,14 @@ import SaplingError from '../lib/SaplingError.js'; * * @returns {object} Permissions */ -export function digest() { +export async function digest() { /* Load the permissions file */ const permissionsPath = path.join(this.dir, this.config.permissions); const formattedPerms = {}; let loadedPerms = {}; try { - loadedPerms = JSON.parse(fs.readFileSync(permissionsPath)); + loadedPerms = JSON.parse(await fs.readFile(permissionsPath)); } catch { console.warn(`Permissions at path: ${permissionsPath} not found.`); } @@ -77,7 +77,7 @@ export function digest() { */ export default async function loadPermissions(next) { /* Digest permissions */ - this.permissions = digest.call(this); + this.permissions = await digest.call(this); /* Loop over the urls in permissions */ for (const url of Object.keys(this.permissions)) { diff --git a/drivers/render/Html.js b/drivers/render/Html.js index 477d207..3ca6d78 100644 --- a/drivers/render/Html.js +++ b/drivers/render/Html.js @@ -6,7 +6,7 @@ */ /* Dependencies */ -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import path from 'node:path'; import _ from 'underscore'; import SaplingError from '../../lib/SaplingError.js'; @@ -37,7 +37,7 @@ export default class HTML extends Interface { /* Read the template file */ let html = ''; try { - html = fs.readFileSync(path.resolve(this.viewsPath, template), 'utf8'); + html = await fs.readFile(path.resolve(this.viewsPath, template), 'utf8'); } catch (error) { return new SaplingError(error); } diff --git a/index.js b/index.js index 44dd15d..ab46c89 100755 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ /* Require native clustering bits */ import cluster from 'node:cluster'; -import fs from 'node:fs'; +import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import process from 'node:process'; @@ -20,6 +20,8 @@ import yargs from 'yargs'; /* eslint-disable-next-line node/file-extension-in-import */ import { hideBin } from 'yargs/helpers'; +import Utils from './lib/Utils.js'; + import App from './app.js'; @@ -30,12 +32,12 @@ const argv = yargs(hideBin(process.argv)).argv; const configPath = path.join(process.cwd(), 'config.json'); let sessionAvailable = false; -if (fs.existsSync(configPath)) { - /* If we have a config file, let's load it */ - const file = fs.readFileSync(configPath); - +/* If we have a config file, let's load it */ +if (await new Utils().exists(configPath)) { /* Parse config, or throw an error if it's malformed */ try { + const file = await fs.readFile(configPath); + const c = JSON.parse(file.toString()); if ('session' in c && 'driver' in c.session) { sessionAvailable = true; diff --git a/lib/Utils.js b/lib/Utils.js index c09a1b2..8364aa5 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -37,22 +37,22 @@ export default class Utils { * * @param {string} dir Directory path */ - getFiles(dir) { + async getFiles(dir) { let results = []; let list; try { - list = fs.readdirSync(dir); + list = await fs.promises.readdir(dir); } catch { throw new SaplingError(`Cannot read directory: ${dir}`); } for (const file of list) { const dirfile = dir + '/' + file; - const stat = fs.statSync(dirfile); + const stat = await fs.promises.stat(dirfile); if (stat && stat.isDirectory()) { /* Recurse into a subdirectory */ - results = results.concat(this.getFiles(dirfile)); + results = results.concat(await this.getFiles(dirfile)); } else { /* Is a file */ results.push(dirfile); @@ -63,6 +63,22 @@ export default class Utils { } + /** + * Check if a file or directory exists + * + * @param {string} file Path to file or directory + * @returns Boolean + */ + async exists(file) { + try { + await fs.promises.access(file, fs.constants.F_OK); + return true; + } catch { + return false; + } + } + + /** * Deep clone an object * diff --git a/test/core/loadConfig.test.js b/test/core/loadConfig.test.js index a8ac1df..3bf6680 100644 --- a/test/core/loadConfig.test.js +++ b/test/core/loadConfig.test.js @@ -16,16 +16,16 @@ test.beforeEach(async t => { }); -test.serial('loads the config', t => { - loadConfig.call(t.context.app); +test.serial('loads the config', async t => { + await loadConfig.call(t.context.app); t.is(t.context.app.config.name, 'untitled'); }); -test.serial('uses default config when no config file is supplied', t => { +test.serial('uses default config when no config file is supplied', async t => { t.context.app.configFile = 'test/_data/config/nonexistent.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.is(t.context.app.config.name, 'untitled'); }); }); @@ -46,7 +46,7 @@ test.serial('loads proper environment config when available', async t => { process.env.NODE_ENV = 'production'; console.log = () => true; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.is(t.context.app.config.secret, 'default'); }); }); @@ -57,7 +57,7 @@ test.serial('loads proper environment config with specified name when available' process.env.NODE_ENV = 'production'; console.log = () => true; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.is(t.context.app.config.secret, 'custom'); }); }); @@ -77,108 +77,108 @@ test.serial('throws error when specified environment config file is mangled', as }); -test.serial('strict off by default', t => { - loadConfig.call(t.context.app, () => { +test.serial('strict off by default', async t => { + await loadConfig.call(t.context.app, () => { t.falsy(t.context.app.config.strict); }); }); -test.serial('strict on when set to true', t => { +test.serial('strict on when set to true', async t => { t.context.app.configFile = 'test/_data/config/strict.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.strict); }); }); -test.serial('strict on when production set to true', t => { +test.serial('strict on when production set to true', async t => { t.context.app.configFile = 'test/_data/config/production.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.strict); }); }); -test.serial('production off by default', t => { - loadConfig.call(t.context.app, () => { +test.serial('production off by default', async t => { + await loadConfig.call(t.context.app, () => { t.falsy(t.context.app.config.production); }); }); -test.serial('production on when set to true', t => { +test.serial('production on when set to true', async t => { t.context.app.configFile = 'test/_data/config/production.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.production); }); }); -test.serial('showError on by default', t => { - loadConfig.call(t.context.app, () => { +test.serial('showError on by default', async t => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.showError); }); }); -test.serial('showError off when production set to true', t => { +test.serial('showError off when production set to true', async t => { t.context.app.configFile = 'test/_data/config/production.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.falsy(t.context.app.config.showError); }); }); -test.serial('cors on by default', t => { - loadConfig.call(t.context.app, () => { +test.serial('cors on by default', async t => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.cors); }); }); -test.serial('cors off when set to false', t => { +test.serial('cors off when set to false', async t => { t.context.app.configFile = 'test/_data/config/cors.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.falsy(t.context.app.config.cors); }); }); -test.serial('cors off when production set to true', t => { +test.serial('cors off when production set to true', async t => { t.context.app.configFile = 'test/_data/config/production.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.falsy(t.context.app.config.cors); }); }); -test.serial('cors on when set to true even if production set to true', t => { +test.serial('cors on when set to true even if production set to true', async t => { t.context.app.configFile = 'test/_data/config/corsProduction.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.cors); }); }); -test.serial('compression off by default', t => { - loadConfig.call(t.context.app, () => { +test.serial('compression off by default', async t => { + await loadConfig.call(t.context.app, () => { t.falsy(t.context.app.config.compression); }); }); -test.serial('compression on when set to true', t => { +test.serial('compression on when set to true', async t => { t.context.app.configFile = 'test/_data/config/compression.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.compression); }); }); -test.serial('compression on when production set to true', t => { +test.serial('compression on when production set to true', async t => { t.context.app.configFile = 'test/_data/config/production.json'; - loadConfig.call(t.context.app, () => { + await loadConfig.call(t.context.app, () => { t.truthy(t.context.app.config.compression); }); }); diff --git a/test/core/loadPermissions.test.js b/test/core/loadPermissions.test.js index 673c149..fcfd156 100644 --- a/test/core/loadPermissions.test.js +++ b/test/core/loadPermissions.test.js @@ -35,10 +35,10 @@ test.beforeEach(async t => { }); -test('loads permissions by string', t => { +test.serial('loads permissions by string', async t => { t.context.app.config.permissions = 'string.json'; - loadPermissions.call(t.context.app); + await loadPermissions.call(t.context.app); t.deepEqual(t.context.app.permissions, { 'get /my-account': { @@ -50,10 +50,10 @@ test('loads permissions by string', t => { }); }); -test('loads permissions by array', t => { +test.serial('loads permissions by array', async t => { t.context.app.config.permissions = 'array.json'; - loadPermissions.call(t.context.app); + await loadPermissions.call(t.context.app); t.deepEqual(t.context.app.permissions, { 'get /my-account': { @@ -66,10 +66,10 @@ test('loads permissions by array', t => { }); }); -test('loads permissions by object', t => { +test.serial('loads permissions by object', async t => { t.context.app.config.permissions = 'object.json'; - loadPermissions.call(t.context.app); + await loadPermissions.call(t.context.app); t.deepEqual(t.context.app.permissions, { 'get /my-account': { @@ -88,7 +88,7 @@ test('loads permissions by object', t => { }); }); -test('creates middleware', t => { +test.serial('creates middleware', async t => { t.plan(7); t.context.app.config.permissions = 'methods.json'; @@ -137,11 +137,11 @@ test('creates middleware', t => { } }; - loadPermissions.call(t.context.app); + await loadPermissions.call(t.context.app); }); -test('warns with non-existent permissions file', async t => { +test.serial('warns with non-existent permissions file', async t => { t.plan(1); t.context.app.config.permissions = 'nonexistent.json'; @@ -157,7 +157,7 @@ test('warns with non-existent permissions file', async t => { await loadPermissions.call(t.context.app); }); -test('throws an error loading permissions with an undefined method', async t => { +test.serial('throws an error loading permissions with an undefined method', async t => { t.context.app.config.permissions = 'undefinedMethod.json'; await t.throwsAsync(async () => { @@ -168,7 +168,7 @@ test('throws an error loading permissions with an undefined method', async t => }) }); -test('throws an error loading permissions with an invalid definition', async t => { +test.serial('throws an error loading permissions with an invalid definition', async t => { t.context.app.config.permissions = 'invalid.json'; await t.throwsAsync(async () => { @@ -179,7 +179,7 @@ test('throws an error loading permissions with an invalid definition', async t = }) }); -test('throws an error loading permissions with an invalid object role definition', async t => { +test.serial('throws an error loading permissions with an invalid object role definition', async t => { t.context.app.config.permissions = 'invalidObject.json'; await t.throwsAsync(async () => { @@ -190,7 +190,7 @@ test('throws an error loading permissions with an invalid object role definition }) }); -test('throws an error loading permissions with an missing object role definition', async t => { +test.serial('throws an error loading permissions with an missing object role definition', async t => { t.context.app.config.permissions = 'incompleteObject.json'; await t.throwsAsync(async () => { diff --git a/test/lib/Utils.test.js b/test/lib/Utils.test.js index 564b535..aa8aec1 100644 --- a/test/lib/Utils.test.js +++ b/test/lib/Utils.test.js @@ -29,8 +29,8 @@ test('generates a random string', t => { t.not(random, random2); }); -test('gets all files in an existing directory', t => { - const files = t.context.utils.getFiles(path.join(__dirname, '../_data/accessible')); +test('gets all files in an existing directory', async t => { + const files = await t.context.utils.getFiles(path.join(__dirname, '../_data/accessible')); t.true(Array.isArray(files)); t.is(files.length, 2); @@ -38,15 +38,15 @@ test('gets all files in an existing directory', t => { t.true(files[1].endsWith('file.txt')); }); -test('throws an error when getting files in a directory with no permissions', t => { - t.throws(() => { - t.context.utils.getFiles(path.join(__dirname, '../_data/inaccessible')); +test('throws an error when getting files in a directory with no permissions', async t => { + await t.throwsAsync(async () => { + await t.context.utils.getFiles(path.join(__dirname, '../_data/inaccessible')); }, {instanceOf: SaplingError}); }); -test('throws an error when getting files in non-existent directory', t => { - t.throws(() => { - t.context.utils.getFiles(path.join(__dirname, '../_data/nonexistent')); +test('throws an error when getting files in non-existent directory', async t => { + await t.throwsAsync(async () => { + await t.context.utils.getFiles(path.join(__dirname, '../_data/nonexistent')); }, {instanceOf: SaplingError}); }); From 65c0f96695376f98f9fa8b10ccfdb298d9f7e690 Mon Sep 17 00:00:00 2001 From: groenroos Date: Sun, 20 Mar 2022 17:09:21 +0000 Subject: [PATCH 2/2] Adjust the way fs is imported --- core/loadConfig.js | 2 +- core/loadController.js | 2 +- core/loadHooks.js | 2 +- core/loadModel.js | 2 +- core/loadPermissions.js | 2 +- drivers/render/Html.js | 2 +- index.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/loadConfig.js b/core/loadConfig.js index 6594678..ab7f691 100644 --- a/core/loadConfig.js +++ b/core/loadConfig.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import yargs from 'yargs'; diff --git a/core/loadController.js b/core/loadController.js index 10626e4..7745052 100644 --- a/core/loadController.js +++ b/core/loadController.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; diff --git a/core/loadHooks.js b/core/loadHooks.js index b1981c2..8d0b465 100644 --- a/core/loadHooks.js +++ b/core/loadHooks.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; diff --git a/core/loadModel.js b/core/loadModel.js index 9527c3d..e2498e0 100644 --- a/core/loadModel.js +++ b/core/loadModel.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; diff --git a/core/loadPermissions.js b/core/loadPermissions.js index eb559b7..b76e359 100644 --- a/core/loadPermissions.js +++ b/core/loadPermissions.js @@ -3,7 +3,7 @@ */ /* Dependencies */ -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import path from 'node:path'; import { console } from '../lib/Cluster.js'; diff --git a/drivers/render/Html.js b/drivers/render/Html.js index 3ca6d78..556b556 100644 --- a/drivers/render/Html.js +++ b/drivers/render/Html.js @@ -6,7 +6,7 @@ */ /* Dependencies */ -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import path from 'node:path'; import _ from 'underscore'; import SaplingError from '../../lib/SaplingError.js'; diff --git a/index.js b/index.js index ab46c89..fb75e52 100755 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ /* Require native clustering bits */ import cluster from 'node:cluster'; -import fs from 'node:fs/promises'; +import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import process from 'node:process';