src/jimpex/frontendFs.js
const path = require('path');
const { provider } = require('jimple');
/**
* This service overwrites the `Jimpex` default `FrontendFs` so it will use the file system
* provided by the Webpack middleware instead of using the real file system.
*/
class WebpackFrontendFs {
/**
* Class constructor.
* @param {DevMiddlewareGetDirectory} getDirectory A function to get the directory the
* Webpack middleware is using.
* @param {DevMiddlewareGetFileSystem} getFileSystem A function to get the virtual file system
* the Webpack middleware uses. It uses a
* Promise in order to avoid accessing it
* before the middleware finishes compiling.
*/
constructor(getDirectory, getFileSystem) {
/**
* A function to get the directory the Webpack middleware is using.
* @type {DevMiddlewareGetDirectory}
*/
this.getDirectory = getDirectory;
/**
* A function that returns a Promise with the virtual file system the Webpack middleware uses.
* @type {DevMiddlewareGetFileSystem}
*/
this.getFileSystem = getFileSystem;
}
/**
* Read a file from the file system.
* @param {string} filepath The path to the file.
* @param {string} [encoding='utf-8'] The text encoding in which the file should be read.
* @return {Promise<string,Error>}
*/
read(filepath, encoding = 'utf-8') {
return this.getFileSystem()
.then((fileSystem) => new Promise((resolve, reject) => {
fileSystem.readFile(this._getPath(filepath), encoding, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
}));
}
/**
* Write a file on the file system.
* @param {string} filepath The path to the file.
* @param {string} data The contents of the file.
* @return {Promise<undefined,Error>}
*/
write(filepath, data) {
return this.getFileSystem()
.then((fileSystem) => new Promise((resolve, reject) => {
fileSystem.writeFile(this._getPath(filepath), data, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
}));
}
/**
* Delete a file from the file system.
* @param {string} filepath The path to the file.
* @return {Promise<undefined,Error>}
*/
delete(filepath) {
return this.getFileSystem()
.then((fileSystem) => new Promise((resolve, reject) => {
fileSystem.unlink(this._getPath(filepath), (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
}));
}
/**
* Generate a path using the virtual file system directory as root.
* @param {string} rest The path you want to prefix with the file system directory.
* @return {string}
* @ignore
* @access protected
*/
_getPath(rest) {
return path.join(this.getDirectory(), rest);
}
}
/**
* Generate a `Provider` with an already defined `getDirectory` and `getFileSystem` functions.
* @example
* // Generate the provider
* const provider = webpackFrontendFs(() => 'some-dir', () => middleware.fs);
* // Register it on the container
* container.register(provider);
* // Getting access to the service instance
* const frontendFs = container.get('frontendFs');
* @param {DevMiddlewareGetDirectory} getDirectory A function to get the directory the
* Webpack middleware is using.
* @param {DevMiddlewareGetFileSystem} getFileSystem A function to get the virtual file system
* the Webpack middleware uses. It uses a
* Promise in order to avoid accessing it
* before the middleware finishes compiling.
* @return {Provider}
*/
const webpackFrontendFs = (getDirectory, getFileSystem) => provider((app) => {
app.set('frontendFs', () => new WebpackFrontendFs(
getDirectory,
getFileSystem
));
});
module.exports = {
WebpackFrontendFs,
webpackFrontendFs,
};