diff --git a/installer.mjs b/installer.mjs index af52f77..7c128a0 100644 --- a/installer.mjs +++ b/installer.mjs @@ -41,11 +41,11 @@ const windowsPlatform = { }; const windowsOtherPlatform = { - source: join(cwd, '7z1701.exe'), + source: join(cwd, '7z1604.exe'), destination: join(cwd, 'other32'), - url: 'https://d.7-zip.org/a/', - filename: '7z1701.exe', - extraName: '7z1701-extra.7z', + url: 'https://www.7-zip.org/a/', + filename: '7z1604.exe', + extraName: '7z1604-extra.7z', extractFolder: '', appLocation: '', binaryFiles: ['7z.exe', '7z.dll', '7z.sfx', '7zCon.sfx'], @@ -53,7 +53,7 @@ const windowsOtherPlatform = { sfxModules: ['7za.dll', '7za.exe', '7zxa.dll'], platform: 'win32', binary: '7z.exe', - extraSourceFile: join(cwd, 'other32', '7z1701-extra.7z'), + extraSourceFile: join(cwd, 'other32', '7z1604-extra.7z'), }; const linuxPlatform = { diff --git a/src/createSfx.ts b/src/createSfx.ts index f113af1..84fb5a0 100644 --- a/src/createSfx.ts +++ b/src/createSfx.ts @@ -133,14 +133,18 @@ export function createSfx( reject: (err: string) => void, progress: (data: any) => any ) { - let directory = - destination != '' && fs.existsSync(destination) - ? destination - : getPath('when'); + let directory = undefined; + if (destination && fs.existsSync(destination)) + directory = destination; + else { + const whenPath = getPath('when'); + if (!whenPath) return reject('Path not found!'); + directory = whenPath; + } + let SfxDirectory = join(directory, 'SfxPackages'); fs.ensureDirSync(SfxDirectory); - let override = - isWindows() && (platform == 'linux' || platform == 'darwin'); + const override = isWindows() && ['linux', 'darwin'].includes(platform); let binaryDirectory = Binary(override); let configFile = join(binaryDirectory.path, 'config.txt'); //let configFile = join(SfxDirectory, 'config.txt'); @@ -166,24 +170,29 @@ export function createSfx( if (text) config.write('ExecuteParameters=' + text + '\n'); config.write(';!@InstallEnd@!' + '\n'); config.close(); - delete options.title; - delete options.prompt; - delete options.beginPrompt; - delete options.progress; - delete options.run; - delete options.runProgram; - delete options.directory; - delete options.execute; - delete options.executeFile; - delete options.parameters; - delete options.executeParameters; - let sfxModule = - type == 'gui' ? '7zwin32.sfx' : '7zCon' + platform + '.sfx'; - let sfx = name.includes(extension) ? name : name + extension; - let list = Array.isArray(files) - ? [configFile].concat(files) - : configFile + ' ' + files; - sfx = join(SfxDirectory, sfx); + [ + 'title', + 'prompt', + 'beginPrompt', + 'progress', + 'run', + 'runProgram', + 'directory', + 'execute', + 'executeFile', + 'parameters', + 'executeParameters' + ].forEach((name) => delete options[name]); + const sfxModule = type === 'gui' + ? '7zwin32.sfx' + : `7zCon${platform}.sfx`; + const sfxFilename = name.includes(extension) + ? name + : name + extension; + const sfx = join(SfxDirectory, sfxFilename); + let list = Array.isArray(files) + ? [configFile, ...files] + : `${configFile} ${files}`; let params = Object.assign(options, { sfx: sfxModule, }); @@ -198,12 +207,10 @@ export function createSfx( if (fs.existsSync(sfx)) { return resolve(sfx); /* c8 ignore next 4 */ - } else { - console.error(data); - return reject( - 'Failed! The Sfx application could not be created!' - ); - } + } + + console.error(data); + return reject('Failed! The Sfx application could not be created!'); }); }) .catch((err: string) => { diff --git a/src/index.ts b/src/index.ts index 51b7607..b047959 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,18 @@ import { Files, ReplaceNativeSeparator, Run } from './utility.js'; import { createSfx } from './createSfx.js'; import { isWindows } from 'node-sys'; +const onProgress = (firstChar: string) => + function(data: string): string[] { + /** + * When a stdout is emitted, parse each line and search for a pattern. When + * the pattern is found, extract the file (or directory) name from it and + * pass it to an array. Finally returns this array. + */ + return data.split('\n') + .filter((line) => line.startsWith(firstChar)) + .map((line) => ReplaceNativeSeparator(line.slice(2))); + } + function retry( command: string | undefined, options: {}, @@ -66,24 +78,7 @@ export const createArchive = reject: (reason: any) => void, progress: (arg0: any) => any ) { - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === '+') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } + const onprogress = onProgress('+'); // Convert array of files into a string if needed. files = Files(files); @@ -178,24 +173,7 @@ export const extractArchive = reject: (reason: any) => void, progress: (arg0: any) => any ) { - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === '-') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } + const onprogress = onProgress('-'); // Create a string that can be parsed by `run`. let command = 'e "' + filepath + '" -o"' + dest + '" '; @@ -241,25 +219,8 @@ export const fullArchive = reject: (reason: any) => void, progress: (arg0: any) => any ) { - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === '-') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } - + const onprogress = onProgress('-'); + // Create a string that can be parsed by `run`. let command = 'x "' + filepath + '" -o"' + dest + '" '; return retry( @@ -330,41 +291,49 @@ export const listArchive = buffer = ''; } - data.split('\n').forEach(function (line) { - // Populate the tech specs of the archive that are passed to the - // resolve handler. - if (line.substr(0, 7) === 'Path = ') { - spec.path = line.substr(7, line.length); - } else if (line.substr(0, 7) === 'Type = ') { - spec.type = line.substr(7, line.length); - } else if (line.substr(0, 9) === 'Method = ') { - spec.method = line.substr(9, line.length); - } else if (line.substr(0, 16) === 'Physical Size = ') { - spec.physicalSize = parseInt( - line.substr(16, line.length), - 10 - ); - } else if (line.substr(0, 15) === 'Headers Size = ') { - spec.headersSize = parseInt( - line.substr(15, line.length), - 10 - ); - } else { - // Parse the stdout to find entries - let res = regex.exec(line); - - if (res) { - let e = { - date: new Date(res[1]), - attr: res[2], - size: parseInt(res[3], 10), - name: ReplaceNativeSeparator(res[5]), - }; - entries.push(e); - } // Line may be incomplete, Save it to the buffer. - else buffer = line; + // Populate the tech specs of the archive that are passed to the + // resolve handler. + type Param = [string, string, Function | null]; + + const params: Param[] = [ + ['Path = ', 'path', null], + ['Type = ', 'type', null], + ['Method = ', 'method', null], + ['Physical Size = ', 'physicalSize', parseInt], + ['Headers Size = ', 'headersSize', parseInt], + ]; + + const lines = data.split('\n'); + + for (const line of lines) { + let lineDone = false; + + for (const [beginning, paramType, fn] of params) { + if (line.startsWith(beginning)) { + const paramValue = line.slice(beginning.length); + spec[paramType] = fn ? fn(paramValue) : paramValue; + lineDone = true; + break; + } } - }); + + if (lineDone) continue; + + // Parse the stdout to find entries + let res = regex.exec(line); + + if (res) { + let e = { + date: new Date(res[1]), + attr: res[2], + size: parseInt(res[3], 10), + name: ReplaceNativeSeparator(res[5]), + }; + entries.push(e); + } // Line may be incomplete, Save it to the buffer. + else buffer = line; + } + return entries; } @@ -433,25 +402,8 @@ export const onlyArchive = files: files, }); - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === '-') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } - + const onprogress = onProgress('-'); + // Create a string that can be parsed by `run`. let command = 'e "' + filepath + '" -o"' + dest + '"'; // Start the command @@ -496,24 +448,7 @@ export const renameArchive = reject: (reason: any) => void, progress: (arg0: any) => any ) { - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === 'U') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } + const onprogress = onProgress('U'); // Convert array of files into a string if needed. files = Files(files); @@ -555,24 +490,7 @@ export const testArchive = reject: (reason: any) => void, progress: (arg0: any) => any ) { - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === 'T') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } + const onprogress = onProgress('T'); // Create a string that can be parsed by `run`. let command = 't "' + filepath + '"'; @@ -618,24 +536,7 @@ export const updateArchive = reject: (reason: any) => void, progress: (arg0: any) => any ) { - /** - * When a stdout is emitted, parse each line and search for a pattern.When - * the pattern is found, extract the file (or directory) name from it and - * pass it to an array. Finally returns this array. - */ - function onprogress(data: string) { - let entries: string[] = []; - data.split('\n').forEach(function (line) { - if (line.substr(0, 1) === 'U') { - entries.push( - ReplaceNativeSeparator( - line.substr(2, line.length) - ) - ); - } - }); - return entries; - } + const onprogress = onProgress('U'); // Convert array of files into a string if needed. files = Files(files); diff --git a/src/utility.ts b/src/utility.ts index 3b75f0b..906bbe4 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -130,38 +130,25 @@ export function Run( } if (switches.files) { - let files = switches.files; + const files = switches.files; delete switches.files; - if (Array.isArray(files)) { - files.forEach(function (s) { - args.push(s); - }); - } else { - args.push(files); - } - - args.push('-r'); - args.push('-aoa'); + const filesArray = Array.isArray(files) ? files : [files]; + args = [...args, ...filesArray, '-r', '-aoa']; } // Add switches to the `args` array. let switchesArray = Switches(switches); - switchesArray.forEach(function (s) { - args.push(s); - }); - // Remove now double quotes. If present in the spawned process 7-Zip will - // read them as part of the paths (e.g.: create a `"archive.7z"` with - // quotes in the file-name); - args.forEach(function (e, i) { - if (!isString(e)) { - return; - } + args = [...args, ...switchesArray]; - if (e.substr(0, 1) !== '-') { - e = e.replace(/^"/, ''); - e = e.replace(/"$/, ''); - args[i] = e; + // Remove double quotes. If present in the spawned process, 7-Zip will + // read them as part of the path (e.g.: create a `"archive.7z"` with + // quotes in the file-name); + args.forEach(function (arg, i) { + if (!isString(arg)) return; + const doubleQuotesMatch = arg.match(/^\"(.+)\"$/); + if (doubleQuotesMatch) { + args[i] = doubleQuotesMatch[1]; } }); // Add bb2 to args array so we get file info @@ -181,7 +168,7 @@ export function Run( let res = reg.exec(data); if (res) { - err = new Error(res[2].substr(0, res[2].length - 1)); + err = new Error(res[2].slice(0, -1)); return err; } return; @@ -216,17 +203,17 @@ export function Run( export const Switches = function (switches: Record) { // Default value for switches switches = switches || {}; - var a = []; + let a = []; // Set default values of boolean switches - switches.so = switches.so === true ? true : false; - switches.spl = switches.spl === true ? true : false; - switches.ssc = switches.ssc === false ? false : true; - switches.ssw = switches.ssw === true ? true : false; - switches.y = switches.y === false ? false : true; - var s; + for (const key of ['so', 'spl', 'ssw']) { + if (switches[key] !== true) switches[key] = false; + } + for (const key of ['ssc', 'y']) { + if (switches[key] !== false) switches[key] = true; + } /*jshint forin:false*/ - for (s in switches) { + for (const s in switches) { // Switches that are set or not. Just add them to the array if they are // present. Differ the `ssc` switch treatment to later in the function. if (switches[s] === true && s !== 'ssc') { @@ -237,19 +224,16 @@ export const Switches = function (switches: Record) { // wrap the value with double quotes. Else just add the switch and its value // to the string. Doubles quotes are used for parsing with a RegExp later. if (!isBool(switches[s])) { - // Special treatment for wildcards if (s === 'wildcards') { + // Special treatment for wildcards a.unshift(switches.wildcards); - } // Allow raw switches to be added to the command, repeating switches like - // -i is not possible otherwise. - else if (s === 'raw') { - switches.raw.forEach(function (rawValue: any) { - a.push(rawValue); - }); - } else if (switches[s].indexOf(' ') === -1) { - a.push('-' + s + switches[s]); + } else if (s === 'raw') { + // Allow raw switches to be added to the command, + // otherwise repeating switches like -i is not possible. + a = [...a, ...switches.raw]; } else { - a.push('-' + s + '"' + switches[s] + '"'); + const quote = switches[s].includes(' ') ? '"' : ''; + a.push(`-${s}${quote}${switches[s]}${quote}`); } }