Skip to content

Commit

Permalink
#789: extract code/text from mobileMessage JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
JoernBerkefeld committed Mar 20, 2023
1 parent 5c0e461 commit 95b27f2
Showing 1 changed file with 204 additions and 5 deletions.
209 changes: 204 additions & 5 deletions lib/metadataTypes/MobileMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const TYPE = require('../../types/mcdev.d');
const MetadataType = require('./MetadataType');
const Util = require('../util/util');
const File = require('../util/file');
const cache = require('../util/cache');

/**
Expand Down Expand Up @@ -156,19 +157,82 @@ class MobileMessage extends MetadataType {
}

/**
* Creates a single Event Definition
* Creates a single item
*
* @param {TYPE.MetadataTypeItem} metadata a single Event Definition
* @param {TYPE.MetadataTypeItem} metadata a single item
* @returns {Promise} Promise
*/
static create(metadata) {
return super.createREST(metadata, '/legacy/v1/beta/mobile/message/');
}
/**
* helper for {@link preDeployTasks} that loads extracted code content back into JSON
*
* @param {TYPE.MetadataTypeItem} metadata a single definition
* @param {string} deployDir directory of deploy files
* @param {string} [templateName] name of the template used to built defintion (prior applying templating)
* @returns {Promise.<string>} code
*/
static async _mergeCode(metadata, deployDir, templateName) {
const fileExtension = 'amp';
templateName = templateName || metadata[this.definition.keyField];
let code;
const codePath = File.normalizePath([
deployDir,
this.definition.type,
templateName + '.' + this.definition.type + '-meta',
]);

if (await File.pathExists(codePath + '.' + fileExtension)) {
code = await File.readFilteredFilename(
[deployDir, this.definition.type],
templateName + '.' + this.definition.type + '-meta',
fileExtension
);
} else {
throw new Error(`Could not find ${codePath}.${fileExtension}`);
}
return code;
}
/**
* helper for {@link parseMetadata} and {@link _buildForNested}
*
* @param {string} code the code of the file
* @returns {{fileExt:string,code:string}} returns found extension and file content
*/
static prepExtractedCode(code) {
const fileExt = 'amp';

return { fileExt, code };
}

/**
* should return only the json for all but asset, query and script that are saved as multiple files
* additionally, the documentation for dataExtension and automation should be returned
*
* @param {string[]} keyArr customerkey of the metadata
* @returns {string[]} list of all files that need to be committed in a flat array ['path/file1.ext', 'path/file2.ext']
*/
static getFilesToCommit(keyArr) {
const path = File.normalizePath([
this.properties.directories.retrieve,
this.buObject.credential,
this.buObject.businessUnit,
this.definition.type,
]);

const fileList = keyArr.flatMap((key) => [
File.normalizePath([path, `${key}.${this.definition.type}-meta.json`]),
File.normalizePath([path, `${key}.${this.definition.type}-meta.amp`]),
]);
return fileList;
}

/**
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} metadata a single query
* @returns {TYPE.MetadataTypeItem} Array with one metadata object and one query string
* @returns {TYPE.CodeExtractItem} Array with one metadata object and one query string
*/
static postRetrieveTasks(metadata) {
// mobileCode
Expand Down Expand Up @@ -199,23 +263,38 @@ class MobileMessage extends MetadataType {
}
}

return metadata;
// extract text/code
const codeArr = [];
// keep between tags
const { fileExt, code } = this.prepExtractedCode(metadata.text, metadata.name);
delete metadata.text;
codeArr.push({
subFolder: null,
fileName: metadata[this.definition.keyField],
fileExt: fileExt,
content: code,
});

return { json: metadata, codeArr: codeArr, subFolder: null };
}

/**
* prepares an event definition for deployment
*
* @param {TYPE.MetadataTypeItem} metadata a single MobileMessage
* @param {string} deployDir directory of deploy files
* @returns {TYPE.MetadataTypeItem} Promise
*/
static preDeployTasks(metadata) {
static async preDeployTasks(metadata, deployDir) {
// mobileCode
metadata.code = cache.getByKey('mobileCode', metadata.code.code);

// mobileKeyword
if (metadata.keyword?.keyword) {
metadata.keyword = cache.getByKey('mobilekeyword', metadata.keyword.keyword);
}
// code
metadata.text = await this._mergeCode(metadata, deployDir);

return metadata;
}
Expand All @@ -242,7 +321,127 @@ class MobileMessage extends MetadataType {
);
}
}
/**
* helper for {@link MetadataType.buildDefinition}
* handles extracted code if any are found for complex types
*
* @param {string} templateDir Directory where metadata templates are stored
* @param {string|string[]} targetDir (List of) Directory where built definitions will be saved
* @param {TYPE.MetadataTypeItem} metadata main JSON file that was read from file system
* @param {TYPE.TemplateMap} templateVariables variables to be replaced in the metadata
* @param {string} templateName name of the template to be built
* @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array
*/
static buildDefinitionForNested(
templateDir,
targetDir,
metadata,
templateVariables,
templateName
) {
return this._buildForNested(
templateDir,
targetDir,
metadata,
templateVariables,
templateName,
'definition'
);
}
/**
* helper for {@link MetadataType.buildTemplate}
* handles extracted code if any are found for complex types
*
* @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating
* @param {string} templateDir Directory where metadata templates are stored
* @param {string|string[]} targetDir (List of) Directory where built definitions will be saved
* @param {TYPE.MetadataTypeItem} metadata main JSON file that was read from file system
* @param {TYPE.TemplateMap} templateVariables variables to be replaced in the metadata
* @param {string} templateName name of the template to be built
* @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array
*/
static buildTemplateForNested(
templateDir,
targetDir,
metadata,
templateVariables,
templateName
) {
return this._buildForNested(
templateDir,
targetDir,
metadata,
templateVariables,
templateName,
'template'
);
}

/**
* helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested}
* handles extracted code if any are found for complex types
*
* @param {string} templateDir Directory where metadata templates are stored
* @param {string|string[]} targetDir (List of) Directory where built definitions will be saved
* @param {TYPE.MetadataTypeItem} metadata main JSON file that was read from file system
* @param {TYPE.TemplateMap} templateVariables variables to be replaced in the metadata
* @param {string} templateName name of the template to be built
* @param {'definition'|'template'} mode defines what we use this helper for
* @returns {Promise.<string[][]>} list of extracted files with path-parts provided as an array
*/
static async _buildForNested(
templateDir,
targetDir,
metadata,
templateVariables,
templateName,
mode
) {
// get code from filesystem
let code = await this._mergeCode(metadata, templateDir, templateName);
// try to remove script tags and decide on file extension (html/ssjs)
const file = this.prepExtractedCode(code, metadata.name);
const fileExt = file.fileExt;
code = file.code;
// apply templating
try {
if (mode === 'definition') {
// replace template variables with their values
code = this.applyTemplateValues(code, templateVariables);
} else if (mode === 'template') {
// replace template values with corresponding variable names
code = this.applyTemplateNames(code, templateVariables);
}
} catch {
throw new Error(
`${this.definition.type}:: Error applying template variables on ${
templateName + '.' + this.definition.type
}-meta.amp.`
);
}

// write to file
const targetDirArr = Array.isArray(targetDir) ? targetDir : [targetDir];
const nestedFilePaths = [];

// keep old name if creating templates, otherwise use new name
const fileName = mode === 'definition' ? metadata[this.definition.keyField] : templateName;

for (const targetDir of targetDirArr) {
File.writeToFile(
[targetDir, this.definition.type],
fileName + '.' + this.definition.type + '-meta',
fileExt,
code
);
nestedFilePaths.push([
targetDir,
this.definition.type,
fileName + '.' + this.definition.type + '-meta.' + fileExt,
]);
}
return nestedFilePaths;
}
/**
* Delete a metadata item from the specified business unit
*
Expand Down

0 comments on commit 95b27f2

Please sign in to comment.