UNPKG

patchwork-mapconverter

Version:

Executable wrapper for https://github.com/ChiefOfGxBxL/WC3MapTranslator

155 lines 16.2 kB
#!/usr/bin/env node 'use strict'; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Enhancements = exports.Converters = exports.PatchworkTranslator = exports.Wc3MapTranslator = void 0; const commander_1 = require("commander"); const metadata_1 = require("./metadata"); const LoggerFactory_1 = require("./logging/LoggerFactory"); const War2JsonService_1 = __importDefault(require("./converter/War2JsonService")); const Json2WarService_1 = __importDefault(require("./converter/Json2WarService")); const EnhancementManager_1 = __importDefault(require("./enhancements/EnhancementManager")); const TriggerDataRegistry_1 = require("./enhancements/TriggerDataRegistry"); const FileBlacklist_1 = require("./enhancements/FileBlacklist"); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const TranslatorRecord_1 = require("./converter/TranslatorRecord"); const Wc3MapTranslator = __importStar(require("./wc3maptranslator")); exports.Wc3MapTranslator = Wc3MapTranslator; const PatchworkTranslator = __importStar(require("./translator")); exports.PatchworkTranslator = PatchworkTranslator; const Converters = __importStar(require("./converter")); exports.Converters = Converters; const Enhancements = __importStar(require("./enhancements")); exports.Enhancements = Enhancements; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-var-requires require('source-map-support').install(); let log; commander_1.program .name(metadata_1.NAME) .version(metadata_1.VERSION) .description(metadata_1.DESCRIPTION) .option('-d, --debug', 'output extra debugging') .option('-si, --smart-imports', 'unpack/compile imports using/into .imp file as reference, ignores .json version if enabled') .addOption(new commander_1.Option('-imp, --imports-folder-name <importsFolderName>', 'map project imports folder name for smart-imports').default(EnhancementManager_1.default.importFolder)) .addOption(new commander_1.Option('-td, --trigger-data <triggerData>', 'TriggerData.txt file location for reading triggers file.').default(path_1.default.join('./', EnhancementManager_1.default.triggerDataPath))) .addOption(new commander_1.Option('--ignore <blacklist>', 'Specify a blacklist location for which files to ignore').default(path_1.default.join('./', EnhancementManager_1.default.ignoreFilelist))) .addOption(new commander_1.Option('-mde, --map-data-extension <extension>', 'File extension given/read (depending on operation) for map data files (w3u, w3d, etc..)').default(EnhancementManager_1.default.mapDataExtension)) .option('-p, --prettify', 'Output textual format should be prettified if format converter supports it.') .option('-ct, --compose-triggers', 'unpack/compile triggers into/from binary/fs+json representation, following options apply only if this is enabled:') .addOption(new commander_1.Option('-sf, --sourceFolder <sourceFolder>', 'Triggers\' source folder to export to/read from trigger related files').default(EnhancementManager_1.default.sourceFolder)) .addOption(new commander_1.Option('-cse, --custom-script-extension <extension>', 'What file extension will be given to all custom scripts').default(EnhancementManager_1.default.scriptExtension)) .addOption(new commander_1.Option('-dis, --disabled-extension <extension>', 'What suffix will file\'s extension get when custom script is disabled').default(EnhancementManager_1.default.disabledExtension)) .addOption(new commander_1.Option('-ge, --gui-extension <extension>', 'What file extension will be given to GUI elements (Triggers and Variables)').default(EnhancementManager_1.default.guiExtension)) .addOption(new commander_1.Option('-cie, --container-info-extension <extension', 'What file extension will be given to trigger category/library/header for metadata').default(EnhancementManager_1.default.containerInfoExtension)) .addOption(new commander_1.Option('-ce, --comment-extension <extension>', 'What file extension will be given to comments').default(EnhancementManager_1.default.commentExtension)) .addOption(new commander_1.Option('-mh, --map-header <filename>', 'What\'s the map header\'s filename').default(EnhancementManager_1.default.mapHeaderFilename)) .hook('preAction', (thisCommand, actionCommand) => { log = LoggerFactory_1.LoggerFactory.createLogger('main'); const options = thisCommand.opts(); log.debug('command:', actionCommand.name()); log.debug('arguments:', actionCommand.args.join(', ')); log.debug('options:', JSON.stringify(thisCommand.opts())); if (options.debug === true) LoggerFactory_1.LoggerFactory.setLogLevel(LoggerFactory_1.LOG_DEBUG); if (options.smartImports === true) EnhancementManager_1.default.smartImport = true; if (options.composeTriggers === true) EnhancementManager_1.default.composeTriggers = true; if (/\\|\//.test(options.importsFolderName)) { throw new Error(`Invalid importsFolderName '${options.importsFolderName}' must not be a path!`); } else { EnhancementManager_1.default.importFolder = options.importsFolderName; } if (/\\|\//.test(options.sourceFolder)) { throw new Error(`Invalid sourceFolder '${options.sourceFolder}' must not be a path!`); } else { EnhancementManager_1.default.sourceFolder = options.sourceFolder; } FileBlacklist_1.FileBlacklist.readBlacklist(options.ignore); if (/\\|\//.test(options.sourceFolder)) { throw new Error(`Invalid importsFolderName '${options.importsFolderName}' must not be a path!`); } else { EnhancementManager_1.default.importFolder = options.importsFolderName; } if (options.customScriptExtension.startsWith('.')) EnhancementManager_1.default.scriptExtension = options.customScriptExtension; if (options.disabledExtension.startsWith('.')) EnhancementManager_1.default.disabledExtension = options.disabledExtension; if (options.guiExtension.startsWith('.')) EnhancementManager_1.default.guiExtension = options.guiExtension; if (options.containerInfoExtension.startsWith('.')) EnhancementManager_1.default.containerInfoExtension = options.containerInfoExtension; if (options.commentExtension.startsWith('.')) EnhancementManager_1.default.commentExtension = options.commentExtension; if (options.mapDataExtension.startsWith('.')) EnhancementManager_1.default.mapDataExtension = options.mapDataExtension; if (options.prettify === true) EnhancementManager_1.default.prettify = true; if (/\\|\//.test(options.mapHeader)) { throw new Error(`Invalid mapHeader '${options.mapHeader}' must not be a path!`); } else { EnhancementManager_1.default.mapHeaderFilename = options.mapHeader; } if (options.triggerData != null && fs_1.default.existsSync(options.triggerData)) { TriggerDataRegistry_1.TriggerDataRegistry.loadTriggerData(options.triggerData); } }); commander_1.program .command('war2json') .description('convert Warcraft III binaries to JSON') .addArgument(new commander_1.Argument('<input>', 'input directory path').argRequired()) .addArgument(new commander_1.Argument('<output>', 'output directory path').argRequired()) .action(async (input, output) => { try { await War2JsonService_1.default.convert(input, output); } catch (exception) { log.fatal(exception); } }); commander_1.program .command('json2war') .description('convert JSON to Warcraft III binaries') .addArgument(new commander_1.Argument('<input>', 'input directory path').argRequired()) .addArgument(new commander_1.Argument('<output>', 'output directory path').argRequired()) .action(async (input, output) => { try { (0, TranslatorRecord_1.SupplementTranslatorRecord)(EnhancementManager_1.default.mapDataExtension); await Json2WarService_1.default.convert(input, output); } catch (exception) { log.fatal(exception); } }); commander_1.program.parse(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUVBLFlBQVksQ0FBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDWix5Q0FBcUQ7QUFDckQseUNBQXVEO0FBRXZELDJEQUFrRTtBQUNsRSxrRkFBeUQ7QUFDekQsa0ZBQXlEO0FBQ3pELDJGQUFrRTtBQUNsRSw0RUFBd0U7QUFDeEUsZ0VBQTREO0FBQzVELGdEQUF1QjtBQUN2Qiw0Q0FBbUI7QUFDbkIsbUVBQXlFO0FBRXpFLHFFQUFzRDtBQTZHN0MsNENBQWdCO0FBNUd6QixrRUFBbUQ7QUE0R3hCLGtEQUFtQjtBQTNHOUMsd0RBQXlDO0FBMkdPLGdDQUFVO0FBMUcxRCw2REFBOEM7QUEwR2Msb0NBQVk7QUF4R3hFLDZJQUE2STtBQUM3SSxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtBQUV2QyxJQUFJLEdBQW9CLENBQUE7QUFFeEIsbUJBQU87S0FDSixJQUFJLENBQUMsZUFBSSxDQUFDO0tBQ1YsT0FBTyxDQUFDLGtCQUFPLENBQUM7S0FDaEIsV0FBVyxDQUFDLHNCQUFXLENBQUM7S0FDeEIsTUFBTSxDQUFDLGFBQWEsRUFBRSx3QkFBd0IsQ0FBQztLQUMvQyxNQUFNLENBQUMsc0JBQXNCLEVBQUUsNEZBQTRGLENBQUM7S0FDNUgsU0FBUyxDQUFDLElBQUksa0JBQU0sQ0FBQyxpREFBaUQsRUFBRSxtREFBbUQsQ0FBQyxDQUFDLE9BQU8sQ0FBQyw0QkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztLQUN0SyxTQUFTLENBQUMsSUFBSSxrQkFBTSxDQUFDLG1DQUFtQyxFQUFFLDBEQUEwRCxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLDRCQUFrQixDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7S0FDbkwsU0FBUyxDQUFDLElBQUksa0JB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