apickfs v12.2.0
🎓 Learning ApickFS
Full documentation for ApickFS lives on the website.
🧩 Why ApickFS:
- Based on cutting edge fs.promises
 - Async Awiat based code
 - No outdated dependencies
 - Utilising latest features of Nodejs 12.14.0 Long Term released
 - Minimal base library
 - Easy to extend
 - Easy to read source code
 - Automatic JSON parsing
 - Auto Subdirectory creation
 
🎰 Available Methods:
Please click on the below method names to go to the documentation of that function
File opeations
- fileExists()
 - fileExistsSync()
 - readByLineNumbers()
 - getLinesCount()
 - writeLines()
 - deleteFile()
 - openFile()
 - writeFile()
 
Directory operations
- directoryExists()
 - directoryExistsSync()
 - getDirectoryEntries()
 - deleteDirectory()
 - openDirectory()
 - writeDirectory()
 
Low level functions
- fileOrFolderExists()
 - readStorage()
 - removeStorage()
 - removeStorageRecursively()
 - storageHandler()
 - writeStorage()
 
Important Notes
- ApickFS requires Node 12.14.0 LTS
 - Feel free to create a github issue if required.
 - It will be great if every Pull request is accompanied by a github issue.
 
Install and Include
Install the ApickFS file Storage.
npm i apickfsMake sure that you are using Nodejs v12.14.0 or above.
Check your node version now:
node -vIn case you need to manage different verions of Node in your system, we strongy reccoment NVM
Including required methods in your file
const { writeFile, deleteFile, deleteDirectory, getDirectoryEntries } = require('apickfs');You can just include the name of the method that you need. Incase you prefer to include the whole library you can do that too.
const apickFileStorage = require('apickfs');In case you decide to include the whole library, you can use any apickFS method using a . (dot)
apickFileStorage.writeFile();
apickFileStorage.deleteFile();
apickFileStorage.deleteDirectory();
apickFileStorage.getDirectoryEntries();Methods for file operations
fileExists()
Arguments: directoryPath , fileName
Result: a promise that resolves into true if file exists and false if it doesnot exist.
Example:
  { fileExists } = require('apickfs');Inside an Async Function :
const {
  const my_file_exists = await fileExists(__dirname, 'my-file.json');
  console.log(my_file_exists);Inside a normal Function :
fileExists(__dirname, 'my-file.json')
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Why differnt arguments for filename and directory path? At several occassions we need to loop over several files in a particular directory. This approach make it a bit flexible in those use cases. And also we have tried to keep the API consistent.
fileExistsSync()
Arguments directoryPath, fileName
Result
true if file exist and false if it doesnot exist.
Examples
const { fileExistsSync } = require('apickfs');const file_exists = fileExistsSync(__dirname, 'my-file.txt');
console.log(file_exists);readByLineNumbers()
Reads the particular line number from a file. In case it's valid JSON file, its automatically parsed to an Object or an Array. We can provide an array of line numbers to read multiple lines at a time. Arguments
const { readByLineNumbers } = require('apickfs');Arguments
- directoryPath required, path to directory
 - fileName required, file name
 - lineNumbers required, the line number or the array of line numbers you want to read.
 
Result apickFS result object succss: ture/false message: A descriptive message. data; An array of lines read from the file.
Examples
Async Function
const myData = await readByLineNumbers(__dirname, 'my-file.txt', 10);
console.log(myData);const myData = await readByLineNumbers(__dirname, 'my-file.txt', [1, 3]);
console.log(myData);Normal Function
readByLineNumbers(__dirname, 'some-file-name.txt', 10)
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });success response
{
  success: true,
  message: 'SUCCESS: 1 lines successfully read from /Users/vivek/practice-apps/apickdb/my-file.txt.',
  data: [ { hello: 'world' } ]
}{
  success: true,
  message: 'SUCCESS: 2 lines successfully read from /Users/vivek/practice-apps/apickdb/my-file.txt.',
  data: [ { hello: 'world' }, { hello: 'world' } ]
}fail response
{
  success: false,
  message: 'Line number index 10 does not exist in /Users/vivek/practice-apps/apickdb/some-file-name.txt.'
}getLinesCount()
Returns a promise that resolves into the total number of lines in the provided file.
Import
const path = require('path');
const { getLinesCount } = require('apickfs');Arguments
- directoryName: required, string, directory path
 - fileName: required, string, filename
 
Result A promise that resolves into an integer of total number of lines in the provided file.
Examples
Async Function
const linesCount = await getLinesCount(path.join(__dirname, 'bigdata'), 'big.txt');
console.log(linesCount);Normal Function
getLinesCount(path.join(__dirname, 'some-folder'), 'my-file.txt')
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Example success response
{
  success: true,
  message: 'SUCCESS: /Users/vivek/practice-apps/apickdb/bigdata/big.txt has total 163845 lines.',
  data: 163845
}Example fail response
{
  success: false,
  message: 'Error: /Users/vivek/practice-apps/apickdb/bigdataxxx doesnot exist.'
}writeLines()
Write a line or several lines to the end of the file.
Import
const { writeLines } = require('apickfs');Arguments
- directoryPath: required, string, path to the directory.
 - fileName: required, string, filename with extension.
 - LinesofData: line of data or an array of lines of data.
 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Async Function
Example 1.
let writestatus = await writeLines(path.join(__dirname, 'some-folder'), 'my-file.txt', [
  'Hello Javascript',
  { Hello: 'node' }
]);
console.log(writestatus);Example 2.
let writestatus = await writeLines(path.join(__dirname), 'my-file.txt', 'Hello Javascript');
console.log(writestatus);Example 3.
let writestatus = await writeLines(path.join(__dirname), 'my-file.txt', { hello: 'hello' });
console.log(writestatus);Normal Function
writeLines(path.join(__dirname), 'my-file.txt', { hello: 'hello' })
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Example success response
{
  success: true,
  message: 'SUCCESS: 2 lines successfully written to my-file.txt.'
}Example fail response
{
  success: false,
  message: 'Error: /Users/vivek/practice-apps/brad-cli/apickdb/my-file.txtxx doesnot exist.'
}deleteFile()
Deletes the file if it exists.
Import
const { deleteFile } = require('apickfs');Arguments
- directoryPath required, string, path of the directory.
 - fileName required, string, name of the file.
 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Async Function
let delstat = await deleteFile((__dirname, 'some-folder'), 'my-file.txt');
console.log(delstat);Normal Function
deleteFile(__dirname, 'todelete.txt')
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Example success response
  {
    success: true,
    message: 'FILE deleted: /Users/vivek/practice-apps/brad-cli/apickdb/todelete.txt'
  }Example fail response
  { success: false, message: 'Directory does not exist: some-folder' }openFile()
Open file just returns an apickResultObject with success: true if the file exists. It created on if
it doesnot exists. It never overwrites an existing file.
On the other hand writeFile() creates the file if it doesnot exist, but overwrites it in case it exists.
Unlike node's native open method, apickFS.openFile() doesnot return a fileHandle. We have special methods to like writeLine to open and add data to files. In most of the cases, you will be using openFile() most of the times.
Import
const { openFile } = require('apickfs');Arguments
- directoryPath: required, string, path to the directory of the file.
 - fileName: required, string, name of the file.
 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Async Function
let openstat = await openFile(path.join(__dirname), 'my-file1.txt');
console.log(openstat);Normal Function
openFile(path.join(__dirname), 'my-file1.txt')
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Example success response
{
  success: true,
  message: 'SUCCESS: /Users/vivek/practice-apps/brad-cli/apickdb/my-file.txt exists.'
}{
  success: true,
  message: 'SUCCESS: /Users/vivek/practice-apps/brad-cli/apickdb/my-file1.txt created.'
}Example fail response
{
  success: false,
  message: 'ERROR: Both directoryPath and filename are required parameters.'
}writeFile()
Write file creates a new file if it doesnot exist. It takes in optional data as well. Incase the file already exists, it complelely overwrites it with the new data. In case new data is not provided, the existing file is replaced with an empty new file.
writeFile() acts differently from openFile() when the file already exists.
Open file never overwrites data
whereas writeFile file overwrites the content of the file.
Just like most of the apickFS functions, it too parses valid Objects and Arrays to JSON by default.
Import
const { writeFile } = require('apickfs');Arguments
- directoryPath: required, string, path to the files directory.
 - fileName: required, string, filename
 - fileData: optional, String/Object/Array, the data for file.
 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Async Function
let writestat = await writeFile(path.join(__dirname), 'to-overwrite.txt', { hello: 'world' });
console.log(writestat);Normal Function
writeFile(path.join(__dirname), 'to-overwrite.txt', { hello: 'world' })
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Example success response
{
  success: true,
  message: 'Success: /Users/vivek/practice-apps/brad-cli/apickdb/to-overwrite.txt successfully created/overwritten.'
}Methods for directory ops
directoryExists()
Returns a promise that resolves to true if the directory exists else it resolves to false.
Import
const { directoryExists } = require('apickfs');Arguments
- directoryPath: required, String, path to the directory.
 
Result
true/false
Examples
Async Function
let dirstat = await directoryExists(path.join(__dirname));
console.log(dirstat);Normal Function
directoryExists(path.join(__dirname))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Example success response
true
Example fail response
false
directoryExistsSync()
Returns true if the directory exists and false in case it doesnot exist.
Import
const { directoryExistsSync } = require('apickfs');Arguments
- directoryPath: required, String, Path to the directory
 
Result
true/false
Examples
Normal Function
let dirStat = directoryExistsSync(path.join(__dirname, 'data'));
console.log(dirStat);Example success response
true
Example fail response
false
getDirectoryEntries()
Recursively lists all the directories and files inside the given directory. Provides us output in several formats depending on the options provided.
Import
const { getDirectoryEntries } = require('apickfs');Arguments
- directoryPath: required, String, path to the directory.
 - options: optional, Object
- maxLevel: integer, default:0(Unlimited)
 - listFiles: boolean, default:
true - listDirectories: boolean, default:
true - getFullPath:boolean, default:
true - ignoreEmptyExtension: boolean, default:
false - mustHaveExtensions: Array of String, default:
[] - mustNotHaveExtensions: Array of String, default:
[] - mustStartWith: Array of String, default:
[] - mustNotStartWith: Array of String, default:
[] - mustInclude: Array of String, default:
[] - mustNotInclude: Array of String, default:
[] - extraDetails: boolean, default:
false 
 
Result
Array of string or Array of Object depnding on the options provided.
Examples
Example to list just files
Example Code
let direntries = await getDirectoryEntries(__dirname, { listDirectories: false, getFullPath: false });
console.log(direntries);Example Response
[
  '.DS_Store',
  'index.js',
  'index2.js',
  'my-file.txt',
  'to-overwrite.txt',
  '.data.db',
  'nestedarray.json',
  'nesteobj.json',
  'colors.json',
  'app.js',
  'post.json',
  'fileOrFolderExists.js',
  'big 4.txt',
  'big 2.txt',
  'big 3.txt',
  'big.txt',
  'my-file1.txt'
];Example to get full path
Example Code
let direntries = await getDirectoryEntries(__dirname, { listDirectories: false });
console.log(direntries);Example Response
[
  '/Users/vivek/practice-apps/brad-cli/apickdb/.DS_Store',
  '/Users/vivek/practice-apps/brad-cli/apickdb/index.js',
  '/Users/vivek/practice-apps/brad-cli/apickdb/index2.js',
  '/Users/vivek/practice-apps/brad-cli/apickdb/my-file.txt',
  '/Users/vivek/practice-apps/brad-cli/apickdb/to-overwrite.txt',
  '/Users/vivek/practice-apps/brad-cli/apickdb/.db-kittens/kittens/.data.db',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/nestedarray.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/nesteobj.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/colors.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/app.js',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/post.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/fileOrFolderExists.js',
  '/Users/vivek/practice-apps/brad-cli/apickdb/bigdata/big 4.txt',
  '/Users/vivek/practice-apps/brad-cli/apickdb/bigdata/big 2.txt',
  '/Users/vivek/practice-apps/brad-cli/apickdb/bigdata/big 3.txt',
  '/Users/vivek/practice-apps/brad-cli/apickdb/bigdata/big.txt',
  '/Users/vivek/practice-apps/brad-cli/apickdb/my-file1.txt'
];Example to get just Json files
Example Code
let direntries = await getDirectoryEntries(__dirname, { listDirectories: false, mustHaveExtensions: ['json'] });
console.log(direntries);Example Response
[
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/nestedarray.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/nesteobj.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/colors.json',
  '/Users/vivek/practice-apps/brad-cli/apickdb/data/post.json'
];Get some Extra details
Example Code
(async () => {
  let direntries = await getDirectoryEntries(__dirname, {
    listDirectories: false,
    mustHaveExtensions: ['json'],
    extraDetails: true
  });
  console.log(direntries);Example Response
[
  {
    type: 'file',
    level: 3,
    fullPath: '/Users/vivek/practice-apps/brad-cli/apickdb/data/nestedarray.json',
    extension: 'json',
    parent: '/Users/vivek/practice-apps/brad-cli/apickdb/data'
  },
  {
    type: 'file',
    level: 3,
    fullPath: '/Users/vivek/practice-apps/brad-cli/apickdb/data/nesteobj.json',
    extension: 'json',
    parent: '/Users/vivek/practice-apps/brad-cli/apickdb/data'
  },
  {
    type: 'file',
    level: 4,
    fullPath: '/Users/vivek/practice-apps/brad-cli/apickdb/data/colors.json',
    extension: 'json',
    parent: '/Users/vivek/practice-apps/brad-cli/apickdb/data'
  },
  {
    type: 'file',
    level: 4,
    fullPath: '/Users/vivek/practice-apps/brad-cli/apickdb/data/post.json',
    extension: 'json',
    parent: '/Users/vivek/practice-apps/brad-cli/apickdb/data'
  }
];Get whose name starts with '.' or 'big'
Example Code
let direntries = await getDirectoryEntries(__dirname, {
  listDirectories: false,
  getFullPath: false,
  mustStartWith: ['.', 'big']
});
console.log(direntries);Example Response
['.DS_Store', '.data.db', 'big 4.txt', 'big 2.txt', 'big 3.txt', 'big.txt'];Example to get just directories
Example Code
let direntries = await getDirectoryEntries(__dirname, {
  listFiles: false,
  getFullPath: false
});
console.log(direntries);Example Response
['t2', '.db-kittens', 'kittens', 'data', '.data', 'bigdata'];deleteDirectory()
Recursively deletes a directory and its contents. In case you want to stop it from deleting if the directory has some content the pass false as second argument.
Import
const { deleteDirectory } = require('apickfs');Arguments
- directoryPath: required, string
 - recursive: optional, boolean, default=
true 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Example Code
let dirstat = await deleteDirectory(path.join(__dirname, 't2'));
console.log(dirstat);Example Response
{
  success: true,
  message: 'Directory deleted: /Users/vivek/practice-apps/brad-cli/apickdb/t2 recursively.'
}openDirectory()
If the directory exists, it returns apickFsResultObject with success set to true. else creates one. openDirectory
never overwrites existing directory. Unlike node's native open it doesnot return any handles.
Import
const { openDirectory } = require('apickfs');Arguments
- directoryPath, required, String, path of the directory to open
 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Example Code
let dirstat = await openDirectory(path.join(__dirname, 't2'));
console.log(dirstat);Example Response
{
  success: true,
  message: 'SUCCESS: /Users/vivek/practice-apps/brad-cli/apickdb/t2 already exists.'
}writeDirectory()
If directory exist, it overwrites it with an empty new directory. If directory doesnot exist, it creates one.
writeDirectory is uselful when you want to make sure that you are starting from an empty foleder. For rest of the cases openDirectory is the right choice.
Import
const { writeDirectory } = require('apickfs');Arguments
- directoryPath: required, String, path to the directory
 
Result apickFS result object succss: ture/false message: A descriptive message.
Examples
Example Code
let dirstat = await writeDirectory(path.join(__dirname, 't2'));
console.log(dirstat);Example Response
{
  success: true,
  message: 'SUCCESS: /Users/vivek/practice-apps/brad-cli/apickdb/t2 updated/overwritten.'
}Low level Methods
Not to be used most of the times. We have specific mehtods of files and directories.
| Parameter Combinations | result | Description | 
|---|---|---|
writeStorage(directoryPath) | Success, Messge | Creates directory | 
writeStorage(directoryPath , fieName) | Success, Messge | Creates or Truncates file | 
writeStorage(directoryPath , fieName, data) | Success, Messge | Creates file. Adds or Overwrites file content with data. | 
removeStorage(directoryPath) | Success, Messge | Removes directory | 
removeStorage(directoryPath , fieName) | Success, Messge | removes file | 
removeStorage(directoryPath,null,true) | Success, Messge | Removes directory recursively | 
removeStorageRecursively(directoryPath) | Success, Messge | Removes directory recursively | 
fileOrFolderExists(<directory/file> path) | true/false | Checks if a directory or a file exists | 
storageHander(<directory/file> path) | true/false , file/directory | Checks if a directory or a file exists and its type. | 
fileOrFolderExists()
check if a file or a directory exists:
apickFileStorage
  .fileOrFolderExists(path.join(__dirname, 'boo'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });It returns true or false
falsecheck if a file or a directory exists:
apickFileStorage
  .fileOrFolderExists(path.join(__dirname, 'boo'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });It takes just one argument and returns true or false
falseExample with a file:
apickFileStorage
  .fileOrFolderExists(path.join(__dirname, 'data', 'text.txt'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });truereadStorage()
readStorage can be used with three different set of arguments. When just one argument is passed it is treated as a directory path. the second argument is used as file name. and the third file is used as data for file.
second and third arguments are optional.
removeStorage()
Removing data.json in the foo directory:
apickFileStorage
  .removeStorage(path.join(__dirname, 'foo'), 'data.json')
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Removing the boo directory (if it is empty):
apickFileStorage
  .removeStorage(path.join(__dirname, 'boo'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });There are two way to remove boo if it's not empty (recursively)
Removing the boo directory (if it is empty):
Way 1 : provide a directory path, keep filename null and pass true for allowing recursive deleting
apickFileStorage
  .removeStorage(path.join(__dirname, 'boo'), null, true)
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Way 2 :
apickFileStorage
  .removeStorageRecursively(path.join(__dirname, 'boo'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });removeStorageRecursively()
removeStorageRecursively is same as removeStorage with third argument for recursive option set to true.
apickFileStorage
  .removeStorageRecursively(path.join(__dirname, 'boo'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });storageHandler()
check if a file or a directory exists and also get its type if it exists.
apickFileStorage
  .storageHander(path.join(__dirname, 'data', 'text.txt'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });{ exists: true, type: 'file' }Example with a folder :
apickFileStorage
  .storageHander(path.join(__dirname, 'data'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });{ exists: true, type: 'directory' }writeStorage()
writeStorage() - the selection of this name has a purpose. Its made up of two words = Write and Storage.
Write stands for both creating and editing whereas Store stands for both files and directories.
Creating a directory called foo in our current directory :
Inside an async function :
(async () => {
  try {
    status = await apickFileStorage.writeStorage(path.join(__dirname, 'foo'));
    console.log(status);
  } catch (err) {
    console.log(err);
  }
})();Outside an async function :
apickFileStorage
  .writeStorage(path.join(__dirname, 'fboo'))
  .then(d => {
    console.log(d);
  })
  .catch(e => {
    console.log(e);
  });Run any one of the above and if all is good you must get a response object similar to it :
{
  success: true,
  message: 'SUCCESS: /Users/vivek/practice-apps/temp/fspromises/foo created.'
}You have a sucess value to check if the opration was success and you have a message that can be logged or shown to the user.
You may use any one of async/await or then/catch approach.
Again, for most of the use cases, we have specific methods for files and directories.