UNPKG

minecraft-utils-shared

Version:

Shared utils for Minecraft Bedrock / Forge development related utilities.

195 lines (187 loc) 8.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _chalk = _interopRequireDefault(require("chalk")); var _fsExtra = _interopRequireDefault(require("fs-extra")); var _path = _interopRequireDefault(require("path")); var _template_file = _interopRequireDefault(require("../formats/template_file.cjs")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @file Minecraft Utils Shared - Template * @license Apache-2.0 * @author Markus@Bordihn.de (Markus Bordihn) */ /** * @returns {string} */ const getTemplatePath = () => { if (process.env) { if ((process.env.npm_lifecycle_script || '').includes('minecraft-bedrock-utils') || (process.env.npm_package_name || '').includes('minecraft-bedrock-utils')) { return '.minecraft-bedrock-utils-templates'; } else if ((process.env.npm_lifecycle_script || '').includes('minecraft-forge-utils') || (process.env.npm_package_name || '').includes('minecraft-forge-utils')) { return '.minecraft-forge-utils-templates'; } } return '.minecraft-utils-shared-templates'; }; // eslint-disable-next-line prefer-const let templatePath = _path.default.join(process.cwd(), getTemplatePath()); /** * Template Processing engine * * The target path could be a simple string for easier operations or * and object for more advanced requirements like Forge Mods. * We expect the targetPath Object in the following format: * { * assetsPath: '', * classPath: '', * dataPath: '', * } * * @param {string} template * @param {object} placeholder * @param {string|object} targetPath */ const processTemplateFile = (template, placeholder, targetPath = '') => { if (!_fsExtra.default.existsSync(template)) { console.error('Unable to find template:', template); return; } if (targetPath && typeof targetPath == 'object') { console.log(_chalk.default.green('🏷️ Processing multi template', template, 'with', placeholder, 'and', targetPath)); } else { if (targetPath && !_fsExtra.default.existsSync(targetPath)) { console.error('Unable to access target path:', targetPath); return; } console.log(_chalk.default.green('🏷️ Processing template', template, 'with', placeholder)); } const templateDefinition = _template_file.default.parse(template, placeholder); templateDefinition.forEach(definition => { const fileName = definition.fileName; let filePath = definition.filePath; // Automatically detect correct target path based on file type. if (targetPath && typeof targetPath == 'object') { switch (definition.fileType) { case _template_file.default.fileType.JAVA: filePath = _path.default.join(targetPath.classPath, definition.filePath); break; case _template_file.default.fileType.RESOURCE: filePath = _path.default.join(targetPath.assetsPath, definition.filePath); break; case _template_file.default.fileType.DATA: filePath = _path.default.join(targetPath.dataPath, definition.filePath); break; case _template_file.default.fileType.DATA_MINECRAFT: filePath = _path.default.join(targetPath.dataPath, '..', definition.filePath); break; } } else if (targetPath) { filePath = _path.default.join(targetPath, definition.filePath); } let content = ''; // Handle different kind of operation based on the patch definition. if (definition.copy) { // Copy src file to dst file, if not already exists if (_fsExtra.default.existsSync(filePath)) { console.info(_chalk.default.red('[Skipping Copy]'), fileName, 'already exists.'); } else { console.info(_chalk.default.green('[Copy]'), fileName); _fsExtra.default.ensureDirSync(_path.default.dirname(filePath)); _fsExtra.default.copyFileSync(definition.copy, filePath); } } else if (definition.create) { // Create new file if (_fsExtra.default.existsSync(filePath)) { console.info(_chalk.default.red('[Skipping Create]'), fileName, 'already exists.'); } else { console.info(_chalk.default.green('[Create]'), fileName); content = definition.code; } } else if (definition.before || definition.after) { // Patch existing files according the "after" or "before" placeholder. // We will only processing the file if the code is not already included! if (filePath && _fsExtra.default.existsSync(filePath)) { content = _fsExtra.default.readFileSync(filePath, 'utf-8'); if (!content) { console.error(_chalk.default.red('[Skipping after/before]'), fileName, 'file is empty.'); } else if (content.includes(definition.code)) { console.info(_chalk.default.yellow('[Skipping after/before]'), fileName, 'code is already injected.'); content = ''; } else if (definition.after) { const insertPositionRegExp = new RegExp(`${escapeRegExp(definition.after)}[ \t]*(\r\n|\n|\r)?`); const insertPosition = content.search(insertPositionRegExp); if (insertPosition != -1) { const insertPositionLength = content.match(insertPositionRegExp)[0].length; console.info(_chalk.default.green('[After]'), 'Inject code into', fileName); content = content.slice(0, insertPosition + insertPositionLength) + definition.code + content.slice(insertPosition + insertPositionLength); } else { console.warn(_chalk.default.yellow('[After]'), 'Unable to find entry point', definition.after, 'in', fileName); } } else if (definition.before) { const insertPosition = content.search(new RegExp(`[ \t]*${escapeRegExp(definition.before)}`)); if (insertPosition != -1) { console.info(_chalk.default.green('[Before]'), 'Inject code into', fileName); content = content.slice(0, insertPosition) + definition.code + content.slice(insertPosition); } else { console.warn(_chalk.default.yellow('[Before]'), 'Unable to find entry point', definition.before, 'in', fileName); } } } else { // Show an error, if the file doesn't exists under the location! console.error(_chalk.default.red('[Skipping after/before]'), fileName, 'file does not exists at', filePath); } } else { // Show an general error for any unknown template option. console.warn(_chalk.default.yellow('[?] Unsupported template option, skipping', fileName, '!')); } if (content) { _fsExtra.default.outputFileSync(filePath, content); } }); }; /** * @param {string} content * @param {object} placeholder * @returns {string} */ const replacePlaceholder = (content, placeholder = {}) => { const newContent = content.replace(/\[\[ --([A-Za-z0-9_. ]+)-- \]\]/g, matchString => { const placeholderString = matchString.replace('[[ --', '').replace('-- ]]', '').trim(); return placeholder[placeholderString] || placeholderString; }); return newContent; }; /** * @param {string} text * @returns {string} */ const escapeRegExp = text => { return text.replace(/[\\(){}[\]^$+*?.]/g, '\\$&'); }; const hasCustomTemplateFiles = () => { return !_fsExtra.default.existsSync(templatePath) ? false : !_fsExtra.default.emptyDirSync(templatePath); }; const getCustomTemplateFiles = () => { if (!_fsExtra.default.existsSync(templatePath)) { return null; } const result = []; _fsExtra.default.readdirSync(templatePath).forEach(file => { const filePath = _path.default.resolve(templatePath, file); if (_fsExtra.default.lstatSync(filePath).isFile()) { result.push(filePath); } }); return result; }; var _default = { getCustomTemplateFiles, hasCustomTemplateFiles, processTemplateFile, replacePlaceholder, templatePath }; exports.default = _default;