UNPKG

18.1 kBSource Map (JSON)View Raw
1{"version":3,"file":"mounter.mjs","names":["spawn","spawnSync","Plist","ValueDict","ValueArray","ValueString","ValueBoolean","Mounter","constructor","options","hdiutil","attach","file","ejectOnExit","devices","_runAttach","_argsAttach","eject","ejectSync","_createEjects","attachSync","_runAttachSync","_runEject","_argsEject","_runEjectSync","args","readonly","push","nobrowse","_fileArg","force","stdouts","proc","stdout","on","data","code","Promise","resolve","reject","once","Error","_parseDevices","Buffer","concat","toString","status","error","startsWith","xml","plist","fromXml","systemEntities","valueCastAs","getValue","castAs","r","value","dict","devEntry","potentiallyMountable","contentHint","get","unmappedContentHint","volumeKind","mountPoint","device","_findRootDevice","length","shutdown","info","process","off"],"sources":["../src/mounter.ts"],"sourcesContent":["import {spawn, spawnSync} from 'node:child_process';\n\nimport {\n\tPlist,\n\tValueDict,\n\tValueArray,\n\tValueString,\n\tValueBoolean\n} from '@shockpkg/plist-dom';\n\nexport interface IMounterOptions {\n\t/**\n\t * The path for hdiutil.\n\t *\n\t * @default 'hdiutil'\n\t */\n\thdiutil?: string | null;\n}\n\nexport interface IMounterAttachOptions {\n\t/**\n\t * Force the devices to be read-only.\n\t */\n\treadonly?: boolean;\n\n\t/**\n\t * Hide any mounted volumes from applications like Finder.\n\t */\n\tnobrowse?: boolean;\n}\n\nexport interface IMounterEjectOptions {\n\t/**\n\t * Forcibly detach.\n\t */\n\tforce?: boolean;\n}\n\nexport interface IMounterDevice {\n\t/**\n\t * The dev-entry hdiutil info.\n\t */\n\tdevEntry: string;\n\n\t/**\n\t * The potentially-mountable hdiutil info.\n\t */\n\tpotentiallyMountable: boolean;\n\n\t/**\n\t * The content-hint hdiutil info.\n\t */\n\tcontentHint?: string;\n\n\t/**\n\t * The unmapped-content-hint hdiutil info.\n\t */\n\tunmappedContentHint?: string;\n\n\t/**\n\t * The volume-kind hdiutil info, if present.\n\t */\n\tvolumeKind?: string;\n\n\t/**\n\t * The mount-point hdiutil info, if present.\n\t */\n\tmountPoint?: string;\n}\n\nexport interface IMounterAttachInfo {\n\t/**\n\t * Device list.\n\t */\n\tdevices: IMounterDevice[];\n\n\t/**\n\t * Eject disk.\n\t */\n\teject(options?: Readonly<IMounterEjectOptions> | null): Promise<void>;\n\n\t/**\n\t * Eject disk.\n\t */\n\tejectSync(options?: Readonly<IMounterEjectOptions> | null): void;\n}\n\n/**\n * Mounter object.\n */\nexport class Mounter {\n\t/**\n\t * The path to hdiutil.\n\t */\n\tpublic hdiutil: string;\n\n\t/**\n\t * Mounter constructor.\n\t *\n\t * @param options Options object.\n\t */\n\tconstructor(options: Readonly<IMounterOptions> | null = null) {\n\t\tthis.hdiutil = (options ? options.hdiutil : null) || 'hdiutil';\n\t}\n\n\t/**\n\t * Attach a disk image.\n\t *\n\t * @param file Path to disk image.\n\t * @param options Options object.\n\t * @param ejectOnExit Eject on exit options, or null.\n\t * @returns Info object.\n\t */\n\tpublic async attach(\n\t\tfile: string,\n\t\toptions: Readonly<IMounterAttachOptions> | null = null,\n\t\tejectOnExit: Readonly<IMounterEjectOptions> | null = null\n\t): Promise<IMounterAttachInfo> {\n\t\tconst devices = await this._runAttach(this._argsAttach(file, options));\n\t\tconst {eject, ejectSync} = this._createEjects(devices);\n\t\treturn {\n\t\t\tdevices,\n\t\t\teject,\n\t\t\tejectSync\n\t\t};\n\t}\n\n\t/**\n\t * Attach a disk image.\n\t *\n\t * @param file Path to disk image.\n\t * @param options Options object.\n\t * @param ejectOnExit Eject on exit options, or null.\n\t * @returns Info object.\n\t */\n\tpublic attachSync(\n\t\tfile: string,\n\t\toptions: Readonly<IMounterAttachOptions> | null = null,\n\t\tejectOnExit: Readonly<IMounterEjectOptions> | null = null\n\t): IMounterAttachInfo {\n\t\t// eslint-disable-next-line no-sync\n\t\tconst devices = this._runAttachSync(this._argsAttach(file, options));\n\t\tconst {eject, ejectSync} = this._createEjects(devices);\n\t\treturn {\n\t\t\tdevices,\n\t\t\teject,\n\t\t\tejectSync\n\t\t};\n\t}\n\n\t/**\n\t * Eject a disk image.\n\t *\n\t * @param file Path to device file or volume mount point.\n\t * @param options Options object.\n\t */\n\tpublic async eject(\n\t\tfile: string,\n\t\toptions: Readonly<IMounterEjectOptions> | null = null\n\t) {\n\t\tawait this._runEject(this._argsEject(file, options));\n\t}\n\n\t/**\n\t * Eject a disk image.\n\t *\n\t * @param file Path to device file or volume mount point.\n\t * @param options Options object.\n\t */\n\tpublic ejectSync(\n\t\tfile: string,\n\t\toptions: Readonly<IMounterEjectOptions> | null = null\n\t) {\n\t\t// eslint-disable-next-line no-sync\n\t\tthis._runEjectSync(this._argsEject(file, options));\n\t}\n\n\t/**\n\t * Create args for attach.\n\t *\n\t * @param file Path to disk image.\n\t * @param options Options object.\n\t * @returns Argument list.\n\t */\n\tprotected _argsAttach(\n\t\tfile: string,\n\t\toptions: Readonly<IMounterAttachOptions> | null = null\n\t) {\n\t\tconst args = ['attach', '-plist'];\n\t\tif (options) {\n\t\t\tif (options.readonly) {\n\t\t\t\targs.push('-readonly');\n\t\t\t}\n\t\t\tif (options.nobrowse) {\n\t\t\t\targs.push('-nobrowse');\n\t\t\t}\n\t\t}\n\t\targs.push(this._fileArg(file));\n\t\treturn args;\n\t}\n\n\t/**\n\t * Create args for eject.\n\t *\n\t * @param file Path to device file or volume mount point.\n\t * @param options Options object.\n\t * @returns Argument list.\n\t */\n\tprotected _argsEject(\n\t\tfile: string,\n\t\toptions: Readonly<IMounterEjectOptions> | null = null\n\t) {\n\t\tconst args = ['eject'];\n\t\tif (options && options.force) {\n\t\t\targs.push('-force');\n\t\t}\n\t\targs.push(this._fileArg(file));\n\t\treturn args;\n\t}\n\n\t/**\n\t * Run hdiutil attach command, returning the devices list on success.\n\t *\n\t * @param args CLI args.\n\t * @returns Devices list.\n\t */\n\tprotected async _runAttach(args: Readonly<string[]>) {\n\t\tconst stdouts: Buffer[] = [];\n\t\tconst proc = spawn(this.hdiutil, args);\n\t\tproc.stdout.on('data', (data: Buffer) => {\n\t\t\tstdouts.push(data);\n\t\t});\n\t\tconst code = await new Promise<number | null>((resolve, reject) => {\n\t\t\tproc.once('exit', resolve);\n\t\t\tproc.once('error', reject);\n\t\t});\n\t\tif (code) {\n\t\t\tthrow new Error(`Attach failed: hdiutil exit code: ${code}`);\n\t\t}\n\t\treturn this._parseDevices(Buffer.concat(stdouts).toString());\n\t}\n\n\t/**\n\t * Run hdiutil attach command, returning the devices list on success.\n\t *\n\t * @param args CLI args.\n\t * @returns Devices list.\n\t */\n\tprotected _runAttachSync(args: Readonly<string[]>) {\n\t\tconst {status, error, stdout} = spawnSync(this.hdiutil, args);\n\t\tif (error) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (status) {\n\t\t\tthrow new Error(`Attach failed: hdiutil exit code: ${status}`);\n\t\t}\n\t\treturn this._parseDevices(stdout.toString());\n\t}\n\n\t/**\n\t * Run hdiutil eject command.\n\t *\n\t * @param args CLI args.\n\t */\n\tprotected async _runEject(args: Readonly<string[]>) {\n\t\tconst proc = spawn(this.hdiutil, args);\n\t\tconst status = await new Promise<number | null>((resolve, reject) => {\n\t\t\tproc.once('exit', resolve);\n\t\t\tproc.once('error', reject);\n\t\t});\n\t\tif (status) {\n\t\t\tthrow new Error(`Eject failed: hdiutil exit code: ${status}`);\n\t\t}\n\t}\n\n\t/**\n\t * Run hdiutil eject command.\n\t *\n\t * @param args CLI args.\n\t */\n\tprotected _runEjectSync(args: Readonly<string[]>) {\n\t\tconst {status, error} = spawnSync(this.hdiutil, args);\n\t\tif (error) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (status) {\n\t\t\tthrow new Error(`Eject failed: hdiutil exit code: ${status}`);\n\t\t}\n\t}\n\n\t/**\n\t * Create file argument from file path.\n\t *\n\t * @param file File path.\n\t * @returns A path for use as argument.\n\t */\n\tprotected _fileArg(file: string) {\n\t\t// Make sure it will not be recognized as option argument.\n\t\treturn file.startsWith('-') ? `./${file}` : file;\n\t}\n\n\t/**\n\t * Parse devices plist into devices list.\n\t *\n\t * @param xml XML plist.\n\t * @returns Devices list.\n\t */\n\tprotected _parseDevices(xml: string) {\n\t\tconst plist = new Plist();\n\t\tplist.fromXml(xml);\n\t\tconst systemEntities = plist\n\t\t\t.valueCastAs(ValueDict)\n\t\t\t.getValue('system-entities')\n\t\t\t.castAs(ValueArray);\n\n\t\tconst r: IMounterDevice[] = [];\n\t\tfor (const value of systemEntities.value) {\n\t\t\tconst dict = value.castAs(ValueDict);\n\t\t\tconst devEntry = dict\n\t\t\t\t.getValue('dev-entry')\n\t\t\t\t.castAs(ValueString).value;\n\t\t\tconst potentiallyMountable = dict\n\t\t\t\t.getValue('potentially-mountable')\n\t\t\t\t.castAs(ValueBoolean).value;\n\t\t\tconst contentHint = dict.get('content-hint');\n\t\t\tconst unmappedContentHint = dict.get('unmapped-content-hint');\n\t\t\tconst volumeKind = dict.get('volume-kind');\n\t\t\tconst mountPoint = dict.get('mount-point');\n\n\t\t\tconst device: IMounterDevice = {\n\t\t\t\tdevEntry,\n\t\t\t\tpotentiallyMountable\n\t\t\t};\n\t\t\tif (contentHint) {\n\t\t\t\tdevice.contentHint = contentHint.castAs(ValueString).value;\n\t\t\t}\n\t\t\tif (unmappedContentHint) {\n\t\t\t\tdevice.unmappedContentHint =\n\t\t\t\t\tunmappedContentHint.castAs(ValueString).value;\n\t\t\t}\n\t\t\tif (volumeKind) {\n\t\t\t\tdevice.volumeKind = volumeKind.castAs(ValueString).value;\n\t\t\t}\n\t\t\tif (mountPoint) {\n\t\t\t\tdevice.mountPoint = mountPoint.castAs(ValueString).value;\n\t\t\t}\n\t\t\tr.push(device);\n\t\t}\n\t\treturn r;\n\t}\n\n\t/**\n\t * Find the root device, null on empty list.\n\t *\n\t * @param devices Device list.\n\t * @returns Root device or null if an empty list.\n\t */\n\tprotected _findRootDevice(devices: Readonly<Readonly<IMounterDevice>[]>) {\n\t\tlet r: IMounterDevice | null = null;\n\t\tfor (const device of devices) {\n\t\t\tif (r === null || r.devEntry.length > device.devEntry.length) {\n\t\t\t\tr = device;\n\t\t\t}\n\t\t}\n\t\treturn r;\n\t}\n\n\t/**\n\t * Create ejects callback from a list of devices.\n\t *\n\t * @param devices Device list.\n\t * @param ejectOnExit Eject on exit options, or null.\n\t * @returns Callback function.\n\t */\n\tprotected _createEjects(\n\t\tdevices: Readonly<Readonly<IMounterDevice>[]>,\n\t\tejectOnExit = null\n\t) {\n\t\t// Find the root device, to use to eject (none possible in theory).\n\t\tlet devEntry = this._findRootDevice(devices)?.devEntry;\n\n\t\tlet shutdown: (() => void) | null = null;\n\t\tconst info = {\n\t\t\t/**\n\t\t\t * The eject callback function.\n\t\t\t *\n\t\t\t * @param options Eject options.\n\t\t\t */\n\t\t\teject: async (options: IMounterEjectOptions | null = null) => {\n\t\t\t\tif (devEntry) {\n\t\t\t\t\tawait this.eject(devEntry, options);\n\t\t\t\t\tdevEntry = '';\n\t\t\t\t\tif (shutdown) {\n\t\t\t\t\t\tprocess.off('exit', shutdown);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * The eject callback function.\n\t\t\t *\n\t\t\t * @param options Eject options.\n\t\t\t */\n\t\t\tejectSync: (options: IMounterEjectOptions | null = null) => {\n\t\t\t\tif (devEntry) {\n\t\t\t\t\t// eslint-disable-next-line no-sync\n\t\t\t\t\tthis.ejectSync(devEntry, options);\n\t\t\t\t\tdevEntry = '';\n\t\t\t\t\tif (shutdown) {\n\t\t\t\t\t\tprocess.off('exit', shutdown);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tif (ejectOnExit) {\n\t\t\t/**\n\t\t\t * Attempt to auto-eject on normal shutdown.\n\t\t\t * Does not catch signals (no clean way in a library).\n\t\t\t * Users can explicitly call process.exit() on signals to use this.\n\t\t\t */\n\t\t\tshutdown = () => {\n\t\t\t\t// eslint-disable-next-line no-sync\n\t\t\t\tinfo.ejectSync(ejectOnExit);\n\t\t\t};\n\t\t\tprocess.once('exit', shutdown);\n\t\t}\n\n\t\treturn info;\n\t}\n}\n"],"mappings":"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"}
\No newline at end of file