@badisi/xbw 1.0.8 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2013-2021 Badisi
1
+ Copyright © 2013-2022 Badisi
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -1,34 +1,58 @@
1
1
  # @badisi/xbw
2
2
 
3
- NodeJS module utility which provides helpful functions to read and/or verify xbox 360 backup iso files
3
+ 🎮 NodeJS module utility which provides helpful functions to read and/or verify xbox360 backup iso files.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@badisi/xbw.svg?color=blue&logo=npm)][npm]
6
- [![npm donwloads](https://img.shields.io/npm/dw/@badisi/xbw.svg?color=blue&logo=npm)][npm-dl]
6
+ [![npm donwloads](https://img.shields.io/npm/dw/@badisi/xbw.svg?color=7986CB&logo=npm)][npm-dl]
7
7
  [![license](https://img.shields.io/badge/license-custom-ff69b4)][license]
8
8
 
9
- [![dependency status](https://img.shields.io/david/badisi/xbw.svg)][david-deps]
9
+ ![darwin-x64](https://img.shields.io/badge/darwin-x64-green)
10
+ ![linux-x64](https://img.shields.io/badge/linux-x64-green)
11
+ ![win32-x64](https://img.shields.io/badge/win32-x64-green)
12
+ ![win32-ia32](https://img.shields.io/badge/win32-ia32-green)
10
13
 
11
14
 
12
15
  ## Installation
13
16
 
14
- `xbw` is pre-built for node and electron.
17
+ **xbw** is pre-built for `node >= 12` and `electron` on latest ****macos****, ****linux**** and ****windows****.
15
18
 
16
19
  ```sh
17
- $ npm install @badisi/xbw --save
20
+ npm install -g @badisi/xbw
18
21
  ```
19
22
 
20
23
  ```sh
21
- $ yarn add @badisi/xbw
24
+ yarn global add @badisi/xbw
22
25
  ```
23
26
 
24
27
  ## Usage
25
28
 
26
- ```js
27
- const { verifyWithAbgx360, getIsosInfo } = require('@badisi/xbw');
29
+ ```
30
+ $ xbw --help
31
+
32
+ Usage:
33
+ $ xbw <command> <file|folder...> [--help] [options]
34
+
35
+ Global Commands:
36
+ verify .... Verify backup iso files integrity against abgx360
37
+ info ...... Extract information from backup iso files
38
+
39
+ Examples:
40
+ $ xbw info backup.iso
41
+ $ xbw info backup1.iso backup2.iso path/to/backups/folder/
42
+ $ xbw verify backup.iso --corrupt --af3 --patchgarbage --patchitanyway
43
+ $ xbw verify backup1.iso backup2.iso path/to/backups/folder
44
+ $ xbw verify backup.iso --html > output-file.html
28
45
  ```
29
46
 
47
+ ## API
30
48
 
31
- ## Methods
49
+ This package can also be installed locally and used as an API.
50
+
51
+ ```js
52
+ const { getIsosInfo, verifyWithAbgx360 } = require('@badisi/xbw');
53
+ ```
54
+
55
+ ---------------------------------------
32
56
 
33
57
  * [getIsosInfo](#getIsosInfo)
34
58
  * [verifyWithAbgx360](#verifyWithAbgx360)
@@ -87,7 +111,7 @@ console.log(isosInfo);
87
111
 
88
112
  ---------------------------------------
89
113
 
90
- <a name="verifiyWithAbgx360"></a>
114
+ <a name="verifyWithAbgx360"></a>
91
115
 
92
116
  ### verifyWithAbgx360(isoPaths: string[], options?: AbgxOptions, onProgress?: (progress: string) => void): Promise<AbgxFile[]>
93
117
 
@@ -124,7 +148,7 @@ const abgxOptions = {
124
148
  html: true
125
149
  };
126
150
 
127
- verifiedWithAbgx360(files, options, (progress) => console.log(progress))
151
+ verifiedWithAbgx360(files, options, console.log)
128
152
  .then(results => console.log(results))
129
153
  .catch(error => console.error(error));
130
154
  // => [{
@@ -145,7 +169,7 @@ Credit
145
169
  License
146
170
  -------
147
171
 
148
- Copyright © 2013-2021 [Badisi](https://github.com/Badisi)
172
+ Copyright © 2013-2022 [Badisi](https://github.com/Badisi)
149
173
 
150
174
  Permission is hereby granted, free of charge, to any person obtaining
151
175
  a copy of this software and associated documentation files (the
package/bin/xbw ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ (async () => {
6
+ const { version } = require('../package.json');
7
+ const { verifyWithAbgx360, getIsosInfo } = require('../index.js');
8
+ const { blue, bold, cyan, dim, gray, green, italic, red, white } = require('@colors/colors/safe');
9
+
10
+ const args = process.argv.slice(2);
11
+
12
+ // Patch console.error so that it is printed in red color
13
+ const originalConsoleError = console.error;
14
+ console.error = (message) => originalConsoleError(red(message));
15
+
16
+ // Parse command line arguments
17
+ try {
18
+ switch (args.shift()) {
19
+ case 'verify':
20
+ await verifyWithAbgx360(args, undefined, console.log);
21
+ break;
22
+ case 'info':
23
+ console.log(cyan(JSON.stringify(getIsosInfo(args), null, 2)));
24
+ break;
25
+ default:
26
+ console.log(blue(bold(' _')));
27
+ console.log(blue(bold(' __ _| |____ __')));
28
+ console.log(blue(bold(' \\ \\/ / \'_ \\ \\ /\\ / /')));
29
+ console.log(blue(bold(' > <| |_) \\ V V / ')));
30
+ console.log(`${blue(bold(' /_/\\_\\_.__/ \\_/\\_/'))} ${green(italic(`v${version}`))}`);
31
+ console.log();
32
+ console.log(` ${white(bold('Usage:'))}`);
33
+ console.log();
34
+ console.log(` ${gray('$')} ${cyan('xbw <command> <file|folder...>')} ${cyan(dim('[--help] [options]'))}`);
35
+ console.log();
36
+ console.log(` ${white(bold('Global Commands:'))}`);
37
+ console.log();
38
+ console.log(` ${cyan('verify')} ${gray('.'.repeat(4))} ${white('Verify backup iso files integrity against abgx360')}`);
39
+ console.log(` ${cyan('info')} ${gray('.'.repeat(6))} ${white('Extract information from backup iso files')}`);
40
+ console.log();
41
+ console.log(` ${white(bold('Examples:'))}`);
42
+ console.log();
43
+ console.log(` ${gray('$')} ${cyan('xbw info backup.iso')}`);
44
+ console.log(` ${gray('$')} ${cyan('xbw info backup1.iso backup2.iso path/to/backups/folder/')}`);
45
+ console.log(` ${gray('$')} ${cyan('xbw verify backup.iso --corrupt --af3 --patchgarbage --patchitanyway')}`);
46
+ console.log(` ${gray('$')} ${cyan('xbw verify backup1.iso backup2.iso path/to/backups/folder')}`);
47
+ console.log(` ${gray('$')} ${cyan('xbw verify backup.iso --html > output-file.html')}`);
48
+ console.log();
49
+ break;
50
+ }
51
+ } catch (error) {
52
+ console.error(error.message);
53
+ }
54
+ })();
package/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- export function verifyWithAbgx360(isoPaths: string[], options?: AbgxOptions, onProgress?: (progress: string) => void): Promise<AbgxFile[]>;
2
1
  export function getIsosInfo(isoPaths: string[]): IsoInfo[];
3
2
  export enum Region {
4
3
  REGION_FREE = 'REGION_FREE',
@@ -19,6 +18,17 @@ export enum Region {
19
18
  NTSC_U = 'NTSC_U',
20
19
  NTSCU_UNKNOW = 'NTSCU_UNKNOWN'
21
20
  }
21
+ export interface IsoInfo {
22
+ file: string;
23
+ titleId: string;
24
+ mediaId: string;
25
+ discCount: number;
26
+ discNumber: number;
27
+ regions: Region[];
28
+ isValid: boolean;
29
+ }
30
+
31
+ export function verifyWithAbgx360(isoPaths: string[], options?: AbgxOptions, onProgress?: (progress: string) => void): Promise<AbgxFile[]>;
22
32
  export enum AbgxStatus {
23
33
  VERIFIED = 0,
24
34
  ERROR = -1,
@@ -124,12 +134,3 @@ export interface AbgxOptions {
124
134
  lang: number;
125
135
  speed: number;
126
136
  }
127
- export interface IsoInfo {
128
- file: string;
129
- titleId: string;
130
- mediaId: string;
131
- discCount: number;
132
- discNumber: number;
133
- regions: Region[];
134
- isValid: boolean;
135
- }
package/index.js CHANGED
@@ -1,60 +1,112 @@
1
- const xbw = require('bindings')('xbw');
1
+ // @ts-check
2
2
 
3
- function verifyWithAbgx360(isoPaths, options, onProgress) {
4
- if (Array.isArray(isoPaths)) {
5
- const abgxOptions = (!options) ? [] : Object
6
- .keys(options)
7
- .map((key) => {
8
- if (typeof options[key] === 'string') {
9
- return `--${key} ${options[key]}`;
10
- } else if (typeof options[key] === 'number') {
11
- return `--${key} ${String(options[key])}`;
12
- }
13
- return `--${key}`;
14
- })
15
- .join(' ')
16
- .split(' ');
3
+ const xbw = require('node-gyp-build')(__dirname);
4
+ const { lstatSync, readdirSync, existsSync } = require('fs');
5
+ const { join } = require('path');
17
6
 
7
+ /** @param {string[]} args */
8
+ const getIsoFilesFromArgs = (args = []) => {
9
+ const files = [];
10
+ args
11
+ .filter(arg => !arg.startsWith('-'))
12
+ .forEach(arg => {
13
+ if (existsSync(arg) && lstatSync(arg).isDirectory()) {
14
+ files.push(...readdirSync(arg).reduce((files, itemName) => {
15
+ const itemPath = join(arg, itemName);
16
+ if (lstatSync(itemPath).isDirectory()) {
17
+ return [...files, ...getIsoFilesFromArgs([itemPath])];
18
+ }
19
+ return /** @type {string[]} */(itemName.endsWith('.iso') ? [...files, itemPath] : files);
20
+ }, /** @type {string[]} */([])));
21
+ } else {
22
+ files.push(arg);
23
+ }
24
+ });
25
+ return files;
26
+ };
27
+
28
+ /** @type {import('./index').verifyWithAbgx360} */
29
+ const verifyWithAbgx360 = (args = [], options, onProgress) => {
30
+ if (Array.isArray(args)) {
31
+ const isoPaths = args.filter(arg => !arg.startsWith('-'));
32
+ const files = getIsoFilesFromArgs(isoPaths);
33
+ if (isoPaths.length && !files.length) {
34
+ throw new Error('Error: xbw.verifyWithAbgx360: no ISO files were found');
35
+ }
36
+
37
+ let abgxOptions = ['--help'];
38
+ if (files.length) {
39
+ abgxOptions = args.filter(arg => arg.startsWith('-'));
40
+ if (options) {
41
+ /**
42
+ * TypeScript is not smart enough to figure out what filter() does.
43
+ * So we need to cast the result as being string[] and not (string | undefined)[].
44
+ */
45
+ const items = /** @type {string[]} */(Object
46
+ .keys(options)
47
+ .map(key => {
48
+ if (typeof options[key] === 'string') {
49
+ return `--${key} ${options[key]}`;
50
+ } else if (typeof options[key] === 'number') {
51
+ return `--${key} ${String(options[key])}`;
52
+ } else if (options[key] === false) {
53
+ return undefined; // no-op
54
+ }
55
+ return `--${key}`;
56
+ })
57
+ .filter(option => option)); // filter out the no-op
58
+ abgxOptions.push(...items);
59
+ }
60
+ }
18
61
  return new Promise((resolve, reject) => {
19
62
  xbw.verifyWithAbgx360(
20
- abgxOptions.concat(isoPaths),
21
- (results, error) => {
63
+ abgxOptions.concat(files),
64
+ (/** @type {any} */ error, /** @type {any[]} */ results, /** @type {string} */ progress) => {
65
+ if (progress && onProgress) {
66
+ if (progress.includes('<loader>')) {
67
+ progress = progress.replace(' ', '&nbsp;');
68
+ }
69
+ onProgress(progress);
70
+ }
22
71
  if (error) {
23
72
  return reject(error);
24
73
  }
25
- return resolve(isoPaths.map((isoPath, index) => {
26
- return { file: isoPath, status: results[index] };
27
- }));
28
- },
29
- (progress) => {
30
- if (onProgress) {
31
- onProgress(progress);
74
+ if (results) {
75
+ return resolve(files.map((file, index) => {
76
+ return { file, status: results?.[index] ?? -1 };
77
+ }));
32
78
  }
33
79
  }
34
80
  );
35
81
  });
36
82
  } else {
37
- throw 'Error: verifyWithAbgx360: `files` parameter should be of type Array';
83
+ throw new Error('Error: xbw.verifyWithAbgx360: `args` parameter should be of type Array');
38
84
  }
39
- }
85
+ };
40
86
 
41
- function getIsosInfo(isoPaths) {
87
+ /** @type {import('./index').getIsosInfo} */
88
+ const getIsosInfo = (isoPaths = []) => {
42
89
  if (Array.isArray(isoPaths)) {
43
- return isoPaths?.map(isoPath => {
44
- try {
45
- return {
46
- ...xbw.getIsoInfo(isoPath),
47
- isValid: true
48
- };
49
- } catch (error) {
50
- console.error(`${error.message}\n${isoPath}`);
51
- return { file: isoPath, isValid: false };
52
- }
53
- });
90
+ const files = getIsoFilesFromArgs(isoPaths);
91
+ if (files.length) {
92
+ return files.map(file => {
93
+ try {
94
+ return {
95
+ ...xbw.getIsoInfo(file),
96
+ isValid: true
97
+ };
98
+ } catch (error) {
99
+ console.error(`Error: xbw.getIsosInfo: ${error.message}\n for file: ${file}`);
100
+ return { file, isValid: false };
101
+ }
102
+ });
103
+ } else {
104
+ throw new Error('Error: xbw.getIsosInfo: no ISO files were found');
105
+ }
54
106
  } else {
55
- throw 'Error: getIsosInfo: `files` parameter should be of type Array';
107
+ throw new Error('Error: xbw.getIsosInfo: `isoPaths` parameter should be of type Array');
56
108
  }
57
- }
109
+ };
58
110
 
59
111
  module.exports = {
60
112
  verifyWithAbgx360,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@badisi/xbw",
3
- "version": "1.0.8",
4
- "description": "Utility to read and/or verify xbox 360 backup iso files",
3
+ "version": "2.0.1",
4
+ "description": "Utility to read and/or verify xbox360 backup iso files",
5
5
  "homepage": "https://github.com/Badisi/xbw",
6
6
  "license": "SEE LICENSE IN file",
7
7
  "author": {
@@ -9,6 +9,9 @@
9
9
  },
10
10
  "main": "./index.js",
11
11
  "types": "./index.d.ts",
12
+ "bin": {
13
+ "xbw": "./bin/xbw"
14
+ },
12
15
  "repository": {
13
16
  "type": "git",
14
17
  "url": "https://github.com/Badisi/xbw.git"
@@ -19,17 +22,20 @@
19
22
  "xkey",
20
23
  "xbox360",
21
24
  "abgx",
25
+ "abgx360",
22
26
  "nodejs",
27
+ "iso",
23
28
  "v8"
24
29
  ],
25
30
  "engines": {
26
- "node": ">=8.5.0"
31
+ "node": ">= 12"
27
32
  },
28
33
  "scripts": {
29
- "install": "prebuild-install --tag-prefix='v'"
34
+ "install": "node-gyp-build"
30
35
  },
31
36
  "dependencies": {
32
- "bindings": "^1.5.0",
33
- "prebuild-install": "^6.0.1"
37
+ "@colors/colors": "^1.5.0",
38
+ "node-addon-api": "^5.0.0",
39
+ "node-gyp-build": "^4.5.0"
34
40
  }
35
41
  }