UNPKG

@shockpkg/dir-projector

Version:

Package for creating Shockwave Director projectors

123 lines (106 loc) 3.51 kB
import { copyFile, mkdir, readFile, stat, writeFile } from 'node:fs/promises'; import { join as pathJoin, basename, dirname } from 'node:path'; import { fsLstatExists } from '@shockpkg/archive-files'; import { Plist, ValueDict, ValueString } from '@shockpkg/plist-dom'; import { trimExtension } from "../../util.mjs"; import { machoTypesFile, machoAppLauncher } from "../../util/mac.mjs"; import { ProjectorOttoMac } from "../../projector/otto/mac.mjs"; import { BundleOtto } from "../otto.mjs"; /** * BundleOttoMac object. */ export class BundleOttoMac extends BundleOtto { /** * ProjectorOttoMac instance. */ /** * BundleOttoMac constructor. * * @param path Output path for the main application. * @param flat Flat bundle. */ constructor(path, flat = false) { super(path, flat); this.projector = this._createProjector(); } /** * @inheritdoc */ get extension() { return '.app'; } /** * Get the launcher name. * * @returns Launcher name. */ _getLauncherName() { return trimExtension(basename(this.path), this.extension, true); } /** * @inheritdoc */ _getProjectorPathNested() { const projName = `${this._getLauncherName()}${this.extension}`; return pathJoin(this.path, 'Contents', 'Resources', projName); } /** * @inheritdoc */ _createProjector() { return new ProjectorOttoMac(this._getProjectorPath()); } /** * @inheritdoc */ async _writeLauncher() { const { path, projector } = this; // Create paths to things to create. const appContents = pathJoin(path, 'Contents'); const appMacOS = pathJoin(appContents, 'MacOS'); const appResources = pathJoin(appContents, 'Resources'); const appInfoPlist = pathJoin(appContents, 'Info.plist'); const appPkgInfo = pathJoin(appContents, 'PkgInfo'); // Read the projector Info.plist. const plist = new Plist(); plist.fromXml(await readFile(projector.infoPlistPath, 'utf8')); const dict = plist.getValue().castAs(ValueDict); // Get the binary path and read the types. const projBinaryPath = projector.binaryPath; const projBinaryTypes = await machoTypesFile(projBinaryPath); // Get the icon path. const projIconName = dict.getValue('CFBundleIconFile').castAs(ValueString).value; const projIconPath = projector.iconPath; // Get the PkgInfo path. const projPkgInfoPath = projector.pkgInfoPath; // Create the launcher binary with the same types and mode. const launcherName = this._getLauncherName(); const launcherPath = pathJoin(appMacOS, launcherName); await mkdir(dirname(launcherPath), { recursive: true }); await writeFile(launcherPath, await machoAppLauncher(projBinaryTypes), { mode: (await stat(projBinaryPath)).mode }); // Copy the projector icon if present. const pathIcon = pathJoin(appResources, projIconName); if (await fsLstatExists(projIconPath)) { await copyFile(projIconPath, pathIcon); } // Copy PkgInfo if present. if (await fsLstatExists(projPkgInfoPath)) { await copyFile(projPkgInfoPath, appPkgInfo); } // Update the executable name in the plist for the launcher. dict.set('CFBundleExecutable', new ValueString(launcherName)); // Write the updated Info.plist. await mkdir(dirname(appInfoPlist), { recursive: true }); await writeFile(appInfoPlist, plist.toXml(), 'utf8'); } } //# sourceMappingURL=mac.mjs.map