Repository: Accenture/sfmc-devtools (js)

Issue:
[TASK] replace existsSync with ensureDir
we use it for files like the config file as well as for folders. in total 40 times at this point

Pull request:
Task/312 task replace existssync with ensuredir
# PR details

## What is the purpose of this pull request? (put an "X" next to an item)

_Please delete options that are not relevant._

- [ ] Documentation update
- [ ] Bug fix
- [ ] New metadata support
- [ ] Enhanced metadata
- [ ] Add a CLI option
- [ ] Add something to the core
- [X] Other, please explain: internal change

## What changes did you make? (Give an overview)

Moved existsSync to sync methods and then added ensureDir where appropriate. closes #312

## Is there anything you'd like reviewers to focus on?

complete https://github.com/Accenture/sfmc-devtools/pull/323 first

## Checklist

- [X] I have performed a self-review of my own code
- [X] I have commented my code, particularly in hard-to-understand areas
- [X] ESLint & Prettier are not outputting errors or warnings
- [X] README.md updated (if applicable)
- [X] CHANGELOG.md updated
- [X] ran `npm run docs` to update developer docs


Patch:
diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md
index b8127130..d31188ed 100644
--- a/docs/dist/documentation.md
+++ b/docs/dist/documentation.md
@@ -782,7 +782,7 @@ FileTransfer MetadataType
     * [._extractCode(metadata)](#Asset._extractCode) ⇒ <code>TYPE.CodeExtractItem</code>
     * [._extractCode_slots(prefix, metadataSlots, codeArr)](#Asset._extractCode_slots) ⇒ <code>void</code>
     * [.getJsonFromFS(dir)](#Asset.getJsonFromFS) ⇒ <code>object</code>
-    * [.findSubType(templateDir, templateName)](#Asset.findSubType) ⇒ <code>TYPE.AssetSubType</code>
+    * [.findSubType(templateDir, templateName)](#Asset.findSubType) ⇒ <code>Promise.&lt;TYPE.AssetSubType&gt;</code>
     * [.readSecondaryFolder(templateDir, typeDirArr, templateName, fileName)](#Asset.readSecondaryFolder) ⇒ <code>TYPE.AssetItem</code>
 
 <a name="Asset.retrieve"></a>
@@ -1091,11 +1091,11 @@ Returns file contents mapped to their fileName without '.json' ending
 
 <a name="Asset.findSubType"></a>
 
-### Asset.findSubType(templateDir, templateName) ⇒ <code>TYPE.AssetSubType</code>
+### Asset.findSubType(templateDir, templateName) ⇒ <code>Promise.&lt;TYPE.AssetSubType&gt;</code>
 check template directory for complex types that open subfolders for their subtypes
 
 **Kind**: static method of [<code>Asset</code>](#Asset)  
-**Returns**: <code>TYPE.AssetSubType</code> - subtype name  
+**Returns**: <code>Promise.&lt;TYPE.AssetSubType&gt;</code> - subtype name  
 
 | Param | Type | Description |
 | --- | --- | --- |
@@ -2799,7 +2799,7 @@ Provides default functionality that can be overwritten by child metadata type cl
     * [.applyTemplateNames(code, templateVariables)](#MetadataType.applyTemplateNames) ⇒ <code>string</code>
     * [.buildDefinitionForNested(templateDir, targetDir, metadata, variables, templateName)](#MetadataType.buildDefinitionForNested) ⇒ <code>Promise.&lt;void&gt;</code>
     * [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#MetadataType.buildTemplateForNested) ⇒ <code>Promise.&lt;void&gt;</code>
-    * [.findSubType(templateDir, templateName)](#MetadataType.findSubType) ⇒ <code>string</code>
+    * [.findSubType(templateDir, templateName)](#MetadataType.findSubType) ⇒ <code>Promise.&lt;string&gt;</code>
     * [.readSecondaryFolder(templateDir, typeDirArr, templateName, fileName, ex)](#MetadataType.readSecondaryFolder) ⇒ <code>object</code>
     * [.buildDefinition(templateDir, targetDir, templateName, variables)](#MetadataType.buildDefinition) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
     * [.checkForErrors(ex)](#MetadataType.checkForErrors) ⇒ <code>string</code>
@@ -3278,11 +3278,11 @@ handles extracted code if any are found for complex types
 
 <a name="MetadataType.findSubType"></a>
 
-### MetadataType.findSubType(templateDir, templateName) ⇒ <code>string</code>
+### MetadataType.findSubType(templateDir, templateName) ⇒ <code>Promise.&lt;string&gt;</code>
 check template directory for complex types that open subfolders for their subtypes
 
 **Kind**: static method of [<code>MetadataType</code>](#MetadataType)  
-**Returns**: <code>string</code> - subtype name  
+**Returns**: <code>Promise.&lt;string&gt;</code> - subtype name  
 
 | Param | Type | Description |
 | --- | --- | --- |
diff --git a/lib/Builder.js b/lib/Builder.js
index c3e49930..011cab2d 100644
--- a/lib/Builder.js
+++ b/lib/Builder.js
@@ -187,7 +187,7 @@ class Builder {
         if (buObject !== null) {
             const builder = new Builder(properties, buObject);
             if (Util.checkMarket(market, properties)) {
-                builder.buildDefinition(selectedType, name, properties.markets[market]);
+                return builder.buildDefinition(selectedType, name, properties.markets[market]);
             }
         }
     }
diff --git a/lib/Retriever.js b/lib/Retriever.js
index d727bd67..43332f08 100644
--- a/lib/Retriever.js
+++ b/lib/Retriever.js
@@ -105,7 +105,6 @@ class Retriever {
                     if (templateVariables && Array.isArray(result)) {
                         // so far we are only doing this for templates, hence the above if-check
                         cache.setMetadata(
-                            this.buObject.mid,
                             type,
                             result.map((element) => element.metadata)
                         );
diff --git a/lib/metadataTypes/AccountUser.js b/lib/metadataTypes/AccountUser.js
index 58a58528..d7cd6c4b 100644
--- a/lib/metadataTypes/AccountUser.js
+++ b/lib/metadataTypes/AccountUser.js
@@ -297,10 +297,6 @@ class AccountUser extends MetadataType {
 
         try {
             const filename = buObject.credential;
-            // ensure docs/roles folder is existing (depends on setup in .mcdevrc.json)
-            if (!File.existsSync(docPath)) {
-                File.mkdirpSync(docPath);
-            }
             // write to disk
             await File.writeToFile(docPath, filename + '.accountUser', 'md', output);
             Util.logger.info(`Created ${docPath}${filename}.accountUser.md`);
diff --git a/lib/metadataTypes/Asset.js b/lib/metadataTypes/Asset.js
index bfef60e4..eab974a2 100644
--- a/lib/metadataTypes/Asset.js
+++ b/lib/metadataTypes/Asset.js
@@ -661,7 +661,7 @@ class Asset extends MetadataType {
 
                 // metadata.views.html.content (mandatory)
                 if (
-                    File.existsSync(
+                    await File.pathExists(
                         File.normalizePath([...readDirArr, `index${subtypeExtension}.html`])
                     )
                 ) {
@@ -704,7 +704,7 @@ class Asset extends MetadataType {
                 subDirArr = [this.definition.type, subType];
                 readDirArr = [deployDir, ...subDirArr];
                 if (
-                    File.existsSync(
+                    await File.pathExists(
                         File.normalizePath([
                             ...readDirArr,
                             `${
@@ -757,7 +757,7 @@ class Asset extends MetadataType {
                 // +++ old webpages / pre-2022 +++
                 // metadata.views.html.content (mandatory)
                 if (
-                    File.existsSync(
+                    await File.pathExists(
                         File.normalizePath([
                             ...readDirArr,
                             `views.html.content${subtypeExtension}.html`,
@@ -787,7 +787,7 @@ class Asset extends MetadataType {
                 // +++ new webpages / 2022+ +++
                 // metadata.content
                 if (
-                    File.existsSync(
+                    await File.pathExists(
                         File.normalizePath([...readDirArr, `content${subtypeExtension}.html`])
                     )
                 ) {
@@ -822,7 +822,7 @@ class Asset extends MetadataType {
                 subDirArr = [this.definition.type, subType];
                 readDirArr = [deployDir, ...subDirArr];
                 if (
-                    File.existsSync(
+                    await File.pathExists(
                         File.normalizePath([
                             ...readDirArr,
                             `${
@@ -883,7 +883,7 @@ class Asset extends MetadataType {
                         if (Object.prototype.hasOwnProperty.call(slotObj.blocks, block)) {
                             const fileName = `${prefix}.[${slot}-${block}]${subtypeExtension}`;
                             if (
-                                File.existsSync(
+                                await File.pathExists(
                                     File.normalizePath([
                                         ...readDirArr,
                                         'blocks',
@@ -1070,7 +1070,7 @@ class Asset extends MetadataType {
         try {
             for (const subtype of this.definition.subTypes) {
                 const currentdir = File.normalizePath([dir, subtype]);
-                if (File.existsSync(currentdir)) {
+                if (File.pathExistsSync(currentdir)) {
                     const files = File.readdirSync(currentdir, { withFileTypes: true });
 
                     files.forEach((dirent) => {
@@ -1124,20 +1124,20 @@ class Asset extends MetadataType {
      *
      * @param {string} templateDir Directory where metadata templates are stored
      * @param {string} templateName name of the metadata file
-     * @returns {TYPE.AssetSubType} subtype name
+     * @returns {Promise.<TYPE.AssetSubType>} subtype name
      */
-    static findSubType(templateDir, templateName) {
+    static async findSubType(templateDir, templateName) {
         const typeDirArr = [this.definition.type];
         let subType;
         for (const st of this.definition.subTypes) {
             const fileNameFull = templateName + '.' + this.definition.type + `-${st}-meta.json`;
             if (
-                File.existsSync(
+                (await File.pathExists(
                     File.normalizePath([templateDir, ...typeDirArr, st, fileNameFull])
-                ) ||
-                File.existsSync(
+                )) ||
+                (await File.pathExists(
                     File.normalizePath([templateDir, ...typeDirArr, st, templateName, fileNameFull])
-                )
+                ))
             ) {
                 subType = st;
                 break;
diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js
index 0a9b440c..ea0ec1fb 100644
--- a/lib/metadataTypes/Automation.js
+++ b/lib/metadataTypes/Automation.js
@@ -154,7 +154,7 @@ class Automation extends MetadataType {
             }
             // remove all fields not listed in Definition for templating
             this.keepTemplateFields(val);
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 [templateDir, this.definition.type].join('/'),
                 originalKey + '.' + this.definition.type + '-meta',
                 val
diff --git a/lib/metadataTypes/Campaign.js b/lib/metadataTypes/Campaign.js
index 36877ed0..4a3a1691 100644
--- a/lib/metadataTypes/Campaign.js
+++ b/lib/metadataTypes/Campaign.js
@@ -43,7 +43,7 @@ class Campaign extends MetadataType {
         const res = await this.client.rest.getBulk(`/hub/v1/campaigns/${id}/assets`);
 
         for (const asset of res.items) {
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 `${retrieveDir}/campaign/${name}/assets/`,
                 asset.id + '.campaignAsset-meta',
                 asset
diff --git a/lib/metadataTypes/DataExtension.js b/lib/metadataTypes/DataExtension.js
index 141fd721..632dc885 100644
--- a/lib/metadataTypes/DataExtension.js
+++ b/lib/metadataTypes/DataExtension.js
@@ -648,9 +648,6 @@ class DataExtension extends MetadataType {
      * @returns {Promise.<boolean>} Promise of success of saving the file
      */
     static async _writeDoc(directory, filename, json, mode, fieldsToKeep) {
-        if (!File.existsSync(directory)) {
-            File.mkdirpSync(directory);
-        }
         let fieldsJson = Object.values(json.Fields);
         if (fieldsToKeep) {
             const newJson = [];
@@ -776,9 +773,7 @@ class DataExtension extends MetadataType {
             this.definition.type,
             `${customerKey}.${this.definition.type}-meta.json`,
         ]);
-        if (File.existsSync(jsonFile)) {
-            File.unlinkSync(jsonFile);
-        }
+        await File.remove(jsonFile);
         // delete local copy: doc/dataExtension/cred/bu/...md
         const mdFile = File.normalizePath([
             this.properties.directories.docs,
@@ -787,9 +782,7 @@ class DataExtension extends MetadataType {
             buObject.businessUnit,
             `${customerKey}.${this.definition.type}.md`,
         ]);
-        if (File.existsSync(mdFile)) {
-            File.unlinkSync(mdFile);
-        }
+        await File.remove(mdFile);
     }
 
     /**
diff --git a/lib/metadataTypes/DataExtract.js b/lib/metadataTypes/DataExtract.js
index 9d93a51f..b00332b4 100644
--- a/lib/metadataTypes/DataExtract.js
+++ b/lib/metadataTypes/DataExtract.js
@@ -65,7 +65,7 @@ class DataExtract extends MetadataType {
 
             // remove all fields listed in Definition for templating
             this.keepTemplateFields(val);
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 [templateDir, this.definition.type].join('/'),
                 originalKey + '.' + this.definition.type + '-meta',
                 JSON.parse(Util.replaceByObject(JSON.stringify(val), templateVariables))
diff --git a/lib/metadataTypes/EventDefinition.js b/lib/metadataTypes/EventDefinition.js
index a24de008..353c63f8 100644
--- a/lib/metadataTypes/EventDefinition.js
+++ b/lib/metadataTypes/EventDefinition.js
@@ -73,7 +73,7 @@ class EventDefinition extends MetadataType {
 
                 // remove all fields listed in Definition for templating
                 this.keepTemplateFields(eventDef);
-                File.writeJSONToFile(
+                await File.writeJSONToFile(
                     [templateDir, this.definition.type].join('/'),
                     originalKey + '.' + this.definition.type + '-meta',
                     JSON.parse(Util.replaceByObject(JSON.stringify(eventDef), templateVariables))
diff --git a/lib/metadataTypes/FileTransfer.js b/lib/metadataTypes/FileTransfer.js
index a8c3b175..e72e7186 100644
--- a/lib/metadataTypes/FileTransfer.js
+++ b/lib/metadataTypes/FileTransfer.js
@@ -65,7 +65,7 @@ class FileTransfer extends MetadataType {
 
             // remove all fields listed in Definition for templating
             this.keepTemplateFields(val);
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 [templateDir, this.definition.type].join('/'),
                 originalKey + '.' + this.definition.type + '-meta',
                 JSON.parse(Util.replaceByObject(JSON.stringify(val), templateVariables))
diff --git a/lib/metadataTypes/ImportFile.js b/lib/metadataTypes/ImportFile.js
index 2b57ef4f..75158523 100644
--- a/lib/metadataTypes/ImportFile.js
+++ b/lib/metadataTypes/ImportFile.js
@@ -62,7 +62,7 @@ class ImportFile extends MetadataType {
 
             // remove all fields listed in Definition for templating
             this.keepTemplateFields(val);
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 [templateDir, this.definition.type].join('/'),
                 originalKey + '.' + this.definition.type + '-meta',
                 JSON.parse(Util.replaceByObject(JSON.stringify(val), templateVariables))
diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js
index c6475011..36dbae30 100644
--- a/lib/metadataTypes/MetadataType.js
+++ b/lib/metadataTypes/MetadataType.js
@@ -208,7 +208,7 @@ class MetadataType {
         // retrieve metadata template
         let metadataStr;
         const typeDirArr = [this.definition.type];
-        const subType = this.findSubType(retrieveDir, key);
+        const subType = await this.findSubType(retrieveDir, key);
         if (subType) {
             typeDirArr.push(subType);
         }
@@ -253,7 +253,7 @@ class MetadataType {
 
         try {
             // write to file
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 [templateDir, ...typeDirArr],
                 key + '.' + this.definition.type + suffix,
                 metadata
@@ -1106,7 +1106,7 @@ class MetadataType {
                     this.keepRetrieveFields(saveClone);
                 }
                 savedResults[originalKey] = saveClone;
-                File.writeJSONToFile(
+                await File.writeJSONToFile(
                     // manage subtypes
                     baseDir,
                     originalKey + subtypeExtension,
@@ -1204,9 +1204,9 @@ class MetadataType {
      *
      * @param {string} templateDir Directory where metadata templates are stored
      * @param {string} templateName name of the metadata file
-     * @returns {string} subtype name
+     * @returns {Promise.<string>} subtype name
      */
-    static findSubType(templateDir, templateName) {
+    static async findSubType(templateDir, templateName) {
         return null;
     }
     /**
@@ -1238,7 +1238,7 @@ class MetadataType {
         // retrieve metadata template
         let metadataStr;
         let typeDirArr = [this.definition.type];
-        const subType = this.findSubType(templateDir, templateName);
+        const subType = await this.findSubType(templateDir, templateName);
         if (subType) {
             typeDirArr.push(subType);
         }
@@ -1301,8 +1301,9 @@ class MetadataType {
             } else {
                 targetDirArr = targetDir;
             }
+
             for (const targetDir of targetDirArr) {
-                File.writeJSONToFile(
+                await File.writeJSONToFile(
                     [targetDir, ...typeDirArr],
                     metadata[this.definition.keyField] + '.' + this.definition.type + suffix,
                     metadata
@@ -1388,9 +1389,7 @@ class MetadataType {
             this.definition.type,
             `${customerKey}.${this.definition.type}-meta.json`,
         ]);
-        if (File.existsSync(jsonFile)) {
-            File.unlinkSync(jsonFile);
-        }
+        await File.remove(jsonFile);
     }
 
     /**
diff --git a/lib/metadataTypes/MobileKeyword.js b/lib/metadataTypes/MobileKeyword.js
index b3286db9..9eb00b42 100644
--- a/lib/metadataTypes/MobileKeyword.js
+++ b/lib/metadataTypes/MobileKeyword.js
@@ -62,7 +62,7 @@ class MobileKeyword extends MetadataType {
             }
             // remove all fields listed in Definition for templating
             this.keepTemplateFields(metadata);
-            File.writeJSONToFile(
+            await File.writeJSONToFile(
                 [templateDir, this.definition.type].join('/'),
                 metadata.keyword + '.' + this.definition.type + '-meta',
                 metadata
diff --git a/lib/metadataTypes/Script.js b/lib/metadataTypes/Script.js
index 91dc90e9..c8eb0f41 100644
--- a/lib/metadataTypes/Script.js
+++ b/lib/metadataTypes/Script.js
@@ -97,14 +97,14 @@ class Script extends MetadataType {
             templateName + '.' + this.definition.type + '-meta',
         ]);
 
-        if (File.existsSync(codePath + '.ssjs')) {
+        if (await File.pathExists(codePath + '.ssjs')) {
             code = await File.readFile(
                 [deployDir, this.definition.type],
                 templateName + '.' + this.definition.type + '-meta',
                 'ssjs'
             );
             code = `<script runat="server">\n${code}</script>`;
-        } else if (File.existsSync(codePath + '.html')) {
+        } else if (await File.pathExists(codePath + '.html')) {
             code = await File.readFile(
                 [deployDir, this.definition.type],
                 templateName + '.' + this.definition.type + '-meta',
diff --git a/lib/util/auth.js b/lib/util/auth.js
index b9b4dd78..3088f486 100644
--- a/lib/util/auth.js
+++ b/lib/util/auth.js
@@ -39,7 +39,7 @@ module.exports = {
                     ? await File.readJson(Util.authFileName)
                     : {};
                 existingAuth[credential] = authObject;
-                File.writeJSONToFile('./', Util.authFileName, existingAuth);
+                await File.writeJSONToFile('./', Util.authFileName, existingAuth);
                 authfile = existingAuth;
             }
         } catch (ex) {
diff --git a/lib/util/devops.js b/lib/util/devops.js
index 35c40130..b164e142 100644
--- a/lib/util/devops.js
+++ b/lib/util/devops.js
@@ -194,7 +194,7 @@ const DevOps = {
             properties.directories.docs,
             'deltaPackage/',
         ]);
-        File.writeJSONToFile(directoryDeltaPkg, 'delta_package', delta);
+        await File.writeJSONToFile(directoryDeltaPkg, 'delta_package', delta);
         this.document(directoryDeltaPkg, delta);
         Util.logger.info(
             `- ✔️  Identified changes: Add/Update=${gitActionsCounter['add/update']}, Move=${gitActionsCounter['move']}, Delete=${gitActionsCounter['delete']}`
diff --git a/lib/util/file.js b/lib/util/file.js
index 8cfc8d72..a54cdcc6 100644
--- a/lib/util/file.js
+++ b/lib/util/file.js
@@ -142,11 +142,9 @@ const File = {
     writeJSONToFile: async function (directory, filename, content) {
         directory = this.filterIllegalPathChars(this.normalizePath(directory));
         filename = this.filterIllegalFilenames(filename);
-        if (!fs.existsSync(directory)) {
-            fs.mkdirpSync(directory);
-        }
+        await fs.ensureDir(directory);
         try {
-            await fs.writeJSON(path.join(directory, filename + '.json'), content, { spaces: 4 });
+            return fs.writeJSON(path.join(directory, filename + '.json'), content, { spaces: 4 });
         } catch (ex) {
             Util.logger.error('File.writeJSONToFile:: error | ' + ex.message);
         }
@@ -267,14 +265,12 @@ const File = {
      */
     writeToFile: async function (directory, filename, filetype, content, encoding) {
         directory = this.filterIllegalPathChars(this.normalizePath(directory));
-        if (!fs.existsSync(directory)) {
-            fs.mkdirpSync(directory);
-        }
+        await fs.ensureDir(directory);
         // filter characters that are illegal for file names in Windows
         filename = this.filterIllegalFilenames(filename);
         const filePath = path.join(directory, filename + '.' + filetype);
         try {
-            if (fs.existsSync(filePath)) {
+            if (await fs.pathExists(filePath)) {
                 Util.logger.debug(`Overwriting: ${filePath}`);
             }
             await fs.writeFile(filePath, content, encoding);
@@ -361,8 +357,8 @@ const File = {
             for (const dirent of raw) {
                 const direntPath = path.join(directory, dirent.name);
                 if (
-                    fs.existsSync(direntPath) &&
-                    fs.lstatSync(direntPath).isDirectory() &&
+                    (await fs.pathExists(direntPath)) &&
+                    (await fs.lstat(direntPath)).isDirectory() &&
                     depth > 0
                 ) {
                     const nestedChildren = await this.readDirectories(
diff --git a/lib/util/init.config.js b/lib/util/init.config.js
index 031426e4..9fd40f01 100644
--- a/lib/util/init.config.js
+++ b/lib/util/init.config.js
@@ -198,15 +198,8 @@ const Init = {
     async createIdeConfigFiles(versionBeforeUpgrade) {
         Util.logger.info('Checking configuration files (existing files will not be changed):');
         const creationLog = [];
-
-        if (!File.existsSync('deploy/')) {
-            File.mkdirpSync('deploy/');
-        }
-
-        if (!File.existsSync('src/cloudPages')) {
-            File.mkdirpSync('src/cloudPages');
-        }
-
+        await File.ensureDir('deploy/');
+        await File.ensureDir('src/cloudPages');
         const relevantForcedUpdates = this._getForcedUpdateList(versionBeforeUpgrade);
 
         // copy in .gitignore (cant be retrieved via npm install directly)
@@ -215,11 +208,11 @@ const Init = {
             Util.boilerplateDirectory,
             'gitignore-template'
         );
-        if (!File.existsSync(gitignoreFileName)) {
+        if (!(await File.pathExists(gitignoreFileName))) {
             Util.logger.debug(`Dependency file not found in ${gitignoreFileName}`);
             return false;
         } else {
-            const fileContent = File.readFileSync(gitignoreFileName, 'utf8');
+            const fileContent = await File.readFile(gitignoreFileName, 'utf8');
             creationLog.push(
                 await this._createIdeConfigFile(
                     ['.' + path.sep, '', '.gitignore'],
@@ -231,14 +224,14 @@ const Init = {
 
         // load file list from boilerplate dir and initiate copy process
         const boilerPlateFilesPath = path.resolve(__dirname, Util.boilerplateDirectory, 'files');
-        const directories = File.readDirectoriesSync(boilerPlateFilesPath, 10, false);
+        const directories = await File.readDirectories(boilerPlateFilesPath, 10, false);
 
         for (const subdir of directories) {
             // walk thru the root of our boilerplate-files  directory and all sub folders
             const curDir = path.join(boilerPlateFilesPath, subdir);
-            for (const file of File.readdirSync(curDir)) {
+            for (const file of await File.readdir(curDir)) {
                 // read all files in these directories
-                if (!File.lstatSync(path.join(curDir, file)).isDirectory()) {
+                if (!(await File.lstat(path.join(curDir, file))).isDirectory()) {
                     // filter entries that are actually folders
                     const fileArr = file.split('.');
                     const ext = '.' + fileArr.pop();
@@ -336,10 +329,10 @@ const Init = {
             fileName
         );
         boilerplateFileContent =
-            boilerplateFileContent || File.readFileSync(boilerplateFileName, 'utf8');
+            boilerplateFileContent || (await File.readFile(boilerplateFileName, 'utf8'));
 
-        if (File.existsSync(fileName)) {
-            const existingFileContent = File.readFileSync(fileName, 'utf8');
+        if (await File.pathExists(fileName)) {
+            const existingFileContent = await File.readFile(fileName, 'utf8');
             if (existingFileContent === boilerplateFileContent) {
                 Util.logger.info(`- ✔️  ${fileName} found. No update needed`);
                 return true;
diff --git a/lib/util/init.git.js b/lib/util/init.git.js
index 157ba4af..55db0de2 100644
--- a/lib/util/init.git.js
+++ b/lib/util/init.git.js
@@ -29,7 +29,7 @@ const Init = {
             return result;
         }
         // 3. test if in git repo
-        const gitRepoFoundInCWD = File.existsSync('.git');
+        const gitRepoFoundInCWD = await File.pathExists('.git');
         let newRepoInitialized = null;
         if (gitRepoFoundInCWD) {
             Util.logger.info(`✔️  Git repository found`);
@@ -37,7 +37,7 @@ const Init = {
         } else {
             Util.logger.warn('No Git repository found. Initializing git:');
             Util.execSync('git', ['init']);
-            if (File.existsSync('.git')) {
+            if (await File.pathExists('.git')) {
                 newRepoInitialized = true;
             } else {
                 Util.logger.error(
diff --git a/lib/util/init.js b/lib/util/init.js
index 444d80f0..e4a2c0ab 100644
--- a/lib/util/init.js
+++ b/lib/util/init.js
@@ -23,7 +23,7 @@ const Init = {
      */
     async initProject(properties, credentialName, skipInteraction) {
         const missingCredentials = this._getMissingCredentials(properties);
-        if (File.existsSync(Util.configFileName) && properties) {
+        if ((await File.pathExists(Util.configFileName)) && properties) {
             // config exists
             if (credentialName) {
                 Util.logger.info(`Updating credential '${credentialName}'`);
diff --git a/lib/util/init.npm.js b/lib/util/init.npm.js
index 7c73e211..e1a6f067 100644
--- a/lib/util/init.npm.js
+++ b/lib/util/init.npm.js
@@ -21,9 +21,9 @@ const Init = {
     async installDependencies(repoName) {
         let fileContent;
         let projectPackageJson;
-        if (File.existsSync('package.json')) {
+        if (await File.pathExists('package.json')) {
             try {
-                fileContent = File.readFileSync('package.json', 'utf8');
+                fileContent = await File.readFile('package.json', 'utf8');
             } catch (ex) {
                 Util.logger.error(
                     'Your package.json was found but seems to be corrupted: ' + ex.message
@@ -68,11 +68,11 @@ const Init = {
             Util.boilerplateDirectory,
             'npm-dependencies.json'
         );
-        if (!File.existsSync(dependencyFile)) {
+        if (!(await File.pathExists(dependencyFile))) {
             Util.logger.debug(`Dependency file not found in ${dependencyFile}`);
             return false;
         }
-        const defaultDependencies = File.readJsonSync(dependencyFile);
+        const defaultDependencies = await File.readJson(dependencyFile);
 
         const loadDependencies = defaultDependencies.filter(
             (name) =>


Test patch:
diff --git a/test/dataExtension.test.js b/test/dataExtension.test.js
index d7736798..c0757f5b 100644
--- a/test/dataExtension.test.js
+++ b/test/dataExtension.test.js
@@ -10,7 +10,6 @@ describe('dataExtension', () => {
     afterEach(() => {
         testUtils.mockReset();
     });
-
     describe('Retrieve ================', () => {
         it('Should retrieve a data extension', async () => {
             // WHEN
@@ -24,8 +23,9 @@ describe('dataExtension', () => {
                 'only one data extension expected'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'retrieve'),
                 await testUtils.getActualFile('childBU_dataextension_test', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'retrieve'),
+
                 'returned metadata was not equal expected'
             );
             assert.equal(
@@ -50,13 +50,13 @@ describe('dataExtension', () => {
                 'two data extensions expected'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'create'),
                 await testUtils.getActualFile('testDataExtension', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'create'),
                 'returned metadata was not equal expected for create'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'update'),
                 await testUtils.getActualFile('childBU_dataextension_test', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'update'),
                 'returned metadata was not equal expected for update'
             );
             assert.equal(
@@ -76,6 +76,7 @@ describe('dataExtension', () => {
                 'childBU_dataextension_test',
                 'testMarket'
             );
+
             // WHEN
             assert.equal(
                 Object.keys(result.dataExtension).length,
@@ -83,8 +84,8 @@ describe('dataExtension', () => {
                 'only one dataExtension expected'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'template'),
                 await testUtils.getActualTemplate('childBU_dataextension_test', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'template'),
                 'returned template was not equal expected'
             );
             // THEN
@@ -94,10 +95,9 @@ describe('dataExtension', () => {
                 'childBU_dataextension_test',
                 'testMarket'
             );
-
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'build'),
                 await testUtils.getActualDeployFile('childBU_dataextension_test', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'build'),
                 'returned deployment file was not equal expected'
             );
             assert.equal(
@@ -124,8 +124,8 @@ describe('dataExtension', () => {
                 'only one dataExtension expected'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'template'),
                 await testUtils.getActualTemplate('childBU_dataextension_test', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'template'),
                 'returned template was not equal expected'
             );
             // THEN
@@ -137,8 +137,8 @@ describe('dataExtension', () => {
             );
 
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'dataExtension', 'build'),
                 await testUtils.getActualDeployFile('childBU_dataextension_test', 'dataExtension'),
+                await testUtils.getExpectedFile('9999999', 'dataExtension', 'build'),
                 'returned deployment file was not equal expected'
             );
             assert.equal(
diff --git a/test/query.test.js b/test/query.test.js
index 97fd0d65..85659e5e 100644
--- a/test/query.test.js
+++ b/test/query.test.js
@@ -20,8 +20,8 @@ describe('query', () => {
             const result = cache.getCache();
             assert.equal(Object.keys(result.query).length, 1, 'only one query expected');
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'get'),
                 await testUtils.getActualFile('testExistingQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'get'),
                 'returned metadata was not equal expected'
             );
             assert.equal(
@@ -41,13 +41,13 @@ describe('query', () => {
             const result = cache.getCache();
             assert.equal(Object.keys(result.query).length, 2, 'two querys expected');
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'post'),
                 await testUtils.getActualFile('testQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'post'),
                 'returned metadata was not equal expected for insert query'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'patch'),
                 await testUtils.getActualFile('testExistingQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'patch'),
                 'returned metadata was not equal expected for insert query'
             );
             assert.equal(
@@ -70,8 +70,8 @@ describe('query', () => {
             // WHEN
             assert.equal(Object.keys(result.query).length, 1, 'only one query expected');
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'template'),
                 await testUtils.getActualTemplate('testExistingQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'template'),
                 'returned template was not equal expected'
             );
             // THEN
@@ -82,8 +82,8 @@ describe('query', () => {
                 'testMarket'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'build'),
                 await testUtils.getActualDeployFile('testExistingQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'build'),
                 'returned deployment file was not equal expected'
             );
             assert.equal(
@@ -106,8 +106,8 @@ describe('query', () => {
             // WHEN
             assert.equal(Object.keys(result.query).length, 1, 'only one query expected');
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'template'),
                 await testUtils.getActualTemplate('testExistingQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'template'),
                 'returned template was not equal expected'
             );
             // THEN
@@ -118,8 +118,8 @@ describe('query', () => {
                 'testMarket'
             );
             assert.deepEqual(
-                await testUtils.getExpectedFile('9999999', 'query', 'build'),
                 await testUtils.getActualDeployFile('testExistingQuery', 'query'),
+                await testUtils.getExpectedFile('9999999', 'query', 'build'),
                 'returned deployment file was not equal expected'
             );
             assert.equal(
diff --git a/test/resources/9999999/query/build-expected.json b/test/resources/9999999/query/build-expected.json
index ed7beb5a..b9350fca 100644
--- a/test/resources/9999999/query/build-expected.json
+++ b/test/resources/9999999/query/build-expected.json
@@ -1,11 +1,8 @@
 {
     "name": "testExistingQuery",
     "key": "testExistingQuery",
-    "description": "updated",
+    "description": "",
     "targetKey": "childBU_dataextension_test",
-    "createdDate": "2022-04-26T15:21:16.453",
-    "modifiedDate": "2022-04-26T16:04:15.88",
     "targetUpdateTypeName": "Overwrite",
-    "isFrozen": false,
     "r__folder_Path": "Query"
 }