UNPKG

@shockpkg/dir-projector

Version:

Package for creating Shockwave Director projectors

461 lines (371 loc) 8.85 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.Projector = void 0; var _path = require("path"); var _archiveFiles = require("@shockpkg/archive-files"); var _fsExtra = _interopRequireDefault(require("fs-extra")); var _util = require("./util"); /** * Projector constructor. * * @param path Output path. */ class Projector extends Object { /** * Make a Shockwave projector. * * @default false */ /** * Splash image file. * * @default null */ /** * Splash image data. * * @default null */ /** * Lingo file. * * @default null */ /** * Lingo data. * * @default null */ /** * Xtras include map. * * @default null */ /** * Nest xtras in a Configuration directory. * * @default false */ /** * Path to hdiutil binary. * * @default null */ /** * Output path. */ constructor(path) { super(); this.shockwave = false; this.splashImageFile = null; this.splashImageData = null; this.lingoFile = null; this.lingoData = null; this.includeXtras = null; this.nestXtrasConfiguration = false; this.pathToHdiutil = null; this.path = void 0; this.path = path; } /** * Config file extension. * * @returns File extension. */ get configExtension() { return '.INI'; } /** * Config file encoding. * * @returns File encoding. */ get configEncoding() { return 'ascii'; } /** * Lingo file name. * * @returns File name. */ get lingoName() { return 'LINGO.INI'; } /** * Lingo file encoding. * * @returns File encoding. */ get lingoEncoding() { return 'ascii'; } /** * Xtras directory name. * * @returns Directory encoding. */ get xtrasName() { return 'xtras'; } /** * Configuration directory name. * * @returns Directory encoding. */ get configurationName() { return 'Configuration'; } /** * Name of a projector trimming the extension, case insensitive. * * @returns Projector name without extension. */ get name() { return (0, _util.trimExtension)((0, _path.dirname)(this.path), this.extension, true); } /** * Config file path. * * @returns Config path. */ get configPath() { const base = (0, _util.trimExtension)(this.path, this.extension, true); return `${base}${this.configExtension}`; } /** * Splash image file path. * * @returns Splash image path. */ get splashImagePath() { const base = (0, _util.trimExtension)(this.path, this.extension, true); return `${base}${this.splashImageExtension}`; } /** * Lingo file path. * * @returns Lingo file path. */ get lingoPath() { return (0, _path.join)((0, _path.dirname)(this.path), this.lingoName); } /** * Get outout Xtras path. * * @returns Output path. */ get xtrasPath() { const cn = this.configurationName; return this.nestXtrasConfiguration && cn ? (0, _path.join)((0, _path.dirname)(this.path), cn, this.xtrasName) : (0, _path.join)((0, _path.dirname)(this.path), this.xtrasName); } /** * Get splash image data if any specified, from data or file. * * @returns Splash image data or null. */ async getSplashImageData() { const { splashImageData, splashImageFile } = this; return splashImageData || (splashImageFile ? _fsExtra.default.readFile(splashImageFile) : null); } /** * Get lingo data if any specified, from data or file. * * @returns Lingo data or null. */ async getLingoData() { const { lingoData, lingoFile } = this; if (typeof lingoData === 'string') { return Buffer.from(lingoData, this.lingoEncoding); } if (Array.isArray(lingoData)) { return Buffer.from(lingoData.join(this.lingoNewline), this.lingoEncoding); } if (lingoData) { return lingoData; } return lingoFile ? _fsExtra.default.readFile(lingoFile) : null; } /** * Get the skeleton file or directory as an Archive instance. * * @param skeleton Skeleton path. * @returns Archive instance. */ async getSkeletonArchive(skeleton) { const stat = await _fsExtra.default.stat(skeleton); if (stat.isDirectory()) { return new _archiveFiles.ArchiveDir(skeleton); } if (!stat.isFile()) { throw new Error('Projector skeleton not file or directory'); } const r = (0, _archiveFiles.createArchiveByFileExtension)(skeleton); if (!r) { throw new Error('Projector skeleton archive file type unknown'); } if (r instanceof _archiveFiles.ArchiveHdi) { const { pathToHdiutil } = this; if (pathToHdiutil) { r.mounterMac.hdiutil = pathToHdiutil; } r.nobrowse = true; } return r; } /** * Get include Xtras as a list of mappings. * * @returns Mappings list. */ getIncludeXtrasMappings() { const { includeXtras } = this; const r = []; if (includeXtras) { for (const src of Object.keys(includeXtras)) { const dest = includeXtras[src]; r.push({ src, dest }); } } return r; } /** * Find the best match for a path in a list of Xtras mappings. * Path search is case-insensitive. * * @param mappings Mappings list. * @param path Path to search for. * @returns Best match or null. */ findIncludeXtrasMappingsBestMatch(mappings, path) { let best = null; let bestScore = -1; for (const map of mappings) { const { src } = map; const relative = src === '' ? path : (0, _util.pathRelativeBase)(path, src, true); if (relative === null || bestScore >= src.length) { continue; } best = { map, relative }; bestScore = src.length; } return best; } /** * Find output path for an Xtra. * * @param mappings Mappings list. * @param path Path to search for. * @returns Output path or null. */ includeXtrasMappingsDest(mappings, path) { const best = this.findIncludeXtrasMappingsBestMatch(mappings, path); if (!best) { return null; } const { map, relative } = best; const base = map.dest || map.src; // eslint-disable-next-line no-nested-ternary return base ? relative ? `${base}/${relative}` : base : relative; } /** * Write out projector with skeleton and config file. * * @param skeleton Skeleton path. * @param configFile Config file. */ async withFile(skeleton, configFile) { const configData = configFile ? await _fsExtra.default.readFile(configFile) : null; await this.withData(skeleton, configData); } /** * Write out projector with skeleton and config data. * * @param skeleton Skeleton path. * @param configData Config data. */ async withData(skeleton, configData) { await this._checkOutput(); await this._writeSkeleton(skeleton); await this._modifySkeleton(); await this._writeConfig(configData); await this._writeSplashImage(); await this._writeLingo(); } /** * Check that output path is valid, else throws. */ async _checkOutput() { for (const p of [this.path, this.configPath, this.splashImagePath, this.lingoPath]) { // eslint-disable-next-line no-await-in-loop if (await _fsExtra.default.pathExists(p)) { throw new Error(`Output path already exists: ${p}`); } } } /** * Write out the projector config file. * * @param configData Config data. */ async _writeConfig(configData) { let data = null; if (typeof configData === 'string') { data = Buffer.from(configData, this.configEncoding); } else if (Array.isArray(data)) { data = Buffer.from(configData.join(this.configNewline), this.configEncoding); } else if (configData) { data = configData; } if (data) { await _fsExtra.default.outputFile(this.configPath, data); } } /** * Write out the projector splash image file. */ async _writeSplashImage() { const data = await this.getSplashImageData(); if (data) { await _fsExtra.default.outputFile(this.splashImagePath, data); } } /** * Write out the projector lingo file. */ async _writeLingo() { const data = await this.getLingoData(); if (data) { await _fsExtra.default.outputFile(this.lingoPath, data); } } /** * Projector file extension. * * @returns File extension. */ } exports.Projector = Projector; //# sourceMappingURL=projector.js.map