magicbell-cli 1.2.0 → 1.3.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # magicbell-cli
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#7410](https://github.com/magicbell/magicbell/pull/7410) [`0554378`](https://github.com/magicbell/magicbell/commit/05543786fcbb67db85079f3a5a920bcfdd54aea8) Thanks [@smeijer](https://github.com/smeijer)! - regen
8
+
3
9
  ## 1.2.0
4
10
 
5
11
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magicbell-cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "MagicBell CLI",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -8,13 +8,9 @@
8
8
  "tar": "^7.5.2"
9
9
  },
10
10
  "bin": {
11
- "magicbell": "bin/magicbell"
11
+ "magicbell": "src/cli.js"
12
12
  },
13
13
  "scripts": {
14
- "postinstall": "node src/install.js install",
15
- "preuninstall": "node src/install.js uninstall",
16
- "prepack": "npx -y pinst --enable",
17
- "postpack": "npx -y pinst --disable",
18
14
  "test": "echo \"Error: no test specified\" && exit 1"
19
15
  },
20
16
  "author": "MagicBell",
package/src/cli.js ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'child_process';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ import { installBinary } from './install.js';
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const BIN_DIR = path.resolve(__dirname, '../bin');
11
+ const BINARY_NAME = process.platform === 'win32' ? 'magicbell.exe' : 'magicbell';
12
+ const BINARY_PATH = path.join(BIN_DIR, BINARY_NAME);
13
+
14
+ async function ensureBinary() {
15
+ if (fs.existsSync(BINARY_PATH)) return;
16
+ await installBinary();
17
+
18
+ if (!fs.existsSync(BINARY_PATH)) {
19
+ throw new Error(`MagicBell binary is missing at ${BINARY_PATH} even after installation.`);
20
+ }
21
+ }
22
+
23
+ async function run() {
24
+ try {
25
+ await ensureBinary();
26
+ } catch (err) {
27
+ console.error(err instanceof Error ? err.message : err);
28
+ process.exit(1);
29
+ }
30
+
31
+ const child = spawn(BINARY_PATH, process.argv.slice(2), {
32
+ stdio: 'inherit',
33
+ });
34
+
35
+ child.on('error', (error) => {
36
+ console.error('Failed to start the MagicBell binary:', error.message);
37
+ process.exit(1);
38
+ });
39
+
40
+ child.on('exit', (code, signal) => {
41
+ if (signal) {
42
+ process.kill(process.pid, signal);
43
+ return;
44
+ }
45
+
46
+ process.exit(code ?? 0);
47
+ });
48
+ }
49
+
50
+ run();
package/src/install.js CHANGED
@@ -1,18 +1,18 @@
1
- #!/usr/bin/env node
2
- 'use strict';
1
+ // based on https://github.com/Nelwhix/go-npm/blob/main/src/index.js
2
+ // adjustments made so bin is installed to ./bin,
3
+ // and used via a lazy-load mechanism instead of during postinstall
3
4
 
4
- /* eslint-disable no-console */
5
-
6
- // copy from https://github.com/Nelwhix/go-npm/blob/main/src/index.js
7
- // adjustments made so bin is installed to ./bin instead of node global .bin folder
8
-
9
- import { exec } from 'child_process';
10
5
  import fs from 'fs';
11
6
  import fetch from 'node-fetch';
12
7
  import path from 'path';
13
8
  import * as tar from 'tar';
9
+ import { fileURLToPath } from 'url';
14
10
  import zlib from 'zlib';
15
11
 
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+ const PACKAGE_ROOT = path.resolve(__dirname, '..');
15
+
16
16
  // Mapping from Node's `process.arch` to Golang's `$GOARCH`
17
17
  const ARCH_MAPPING = {
18
18
  ia32: '386',
@@ -29,43 +29,7 @@ const PLATFORM_MAPPING = {
29
29
  freebsd: 'freebsd',
30
30
  };
31
31
 
32
- // to get the path where npm binaries are stored
33
- function getInstallationPath(callback) {
34
- exec('npm --v', (err, stdout, _stderr) => {
35
- const npmVersion = parseFloat(stdout.trim());
36
-
37
- // npm bin was deprecated after v9 https://github.blog/changelog/2022-10-24-npm-v9-0-0-released/
38
- if (npmVersion < 9) {
39
- exec('npm bin -g', (err, stdout, stderr) => {
40
- let dir = null;
41
-
42
- if (err || stderr || !stdout || stdout.length === 0) {
43
- throw new Error('Could not get installation path');
44
- } else {
45
- dir = stdout.trim();
46
- }
47
-
48
- fs.mkdirSync(dir, { recursive: true });
49
- callback(null, dir);
50
- });
51
- } else {
52
- exec('npm prefix -g', (err, stdout, stderr) => {
53
- let dir = null;
54
-
55
- if (err || stderr || !stdout || stdout.length === 0) {
56
- throw new Error('Could not get installation path');
57
- } else {
58
- dir = stdout.trim() + '/bin';
59
- }
60
-
61
- fs.mkdirSync(dir, { recursive: true });
62
- callback(null, dir);
63
- });
64
- }
65
- });
66
- }
67
-
68
- function verifyAndPlaceBinary(binName, binPath, callback) {
32
+ function verifyAndPlaceBinary(binName, binPath) {
69
33
  const targetPath = path.join(binPath, binName);
70
34
 
71
35
  if (!fs.existsSync(targetPath)) {
@@ -77,8 +41,6 @@ function verifyAndPlaceBinary(binName, binPath, callback) {
77
41
  } catch (err) {
78
42
  // ignore on Windows
79
43
  }
80
-
81
- callback();
82
44
  }
83
45
 
84
46
  function validateConfiguration(packageJson) {
@@ -103,34 +65,28 @@ function validateConfiguration(packageJson) {
103
65
  }
104
66
  }
105
67
 
106
- function parsePackageJson() {
68
+ function loadConfiguration() {
107
69
  if (!(process.arch in ARCH_MAPPING)) {
108
- console.error('Installation is not supported for this architecture: ' + process.arch);
109
- return;
70
+ throw new Error('Installation is not supported for this architecture: ' + process.arch);
110
71
  }
111
72
 
112
73
  if (!(process.platform in PLATFORM_MAPPING)) {
113
- console.error('Installation is not supported for this platform: ' + process.platform);
114
- return;
74
+ throw new Error('Installation is not supported for this platform: ' + process.platform);
115
75
  }
116
76
 
117
- const packageJsonPath = path.join('.', 'package.json');
77
+ const packageJsonPath = path.join(PACKAGE_ROOT, 'package.json');
118
78
  if (!fs.existsSync(packageJsonPath)) {
119
- console.error(
120
- 'Unable to find package.json. ' + 'Please run this script at root of the package you want to be installed',
121
- );
122
- return;
79
+ throw new Error('Unable to find package.json. Please run this script at the root of the package.');
123
80
  }
124
81
 
125
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
82
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
126
83
  const error = validateConfiguration(packageJson);
127
84
  if (error && error.length > 0) {
128
- console.error('Invalid package.json: ' + error);
129
- return;
85
+ throw new Error('Invalid package.json: ' + error);
130
86
  }
131
87
 
132
88
  let binName = packageJson.goBinary.name;
133
- const binPath = packageJson.goBinary.path;
89
+ const binPath = path.resolve(PACKAGE_ROOT, packageJson.goBinary.path);
134
90
  let url = packageJson.goBinary.url;
135
91
  let version = packageJson.goBinary.binaryVersion || packageJson.version;
136
92
  if (version[0] === 'v') version = version.substr(1);
@@ -146,10 +102,10 @@ function parsePackageJson() {
146
102
  url = url.replace(/{{bin_name}}/g, binName);
147
103
 
148
104
  return {
149
- binName: binName,
150
- binPath: binPath,
151
- url: url,
152
- version: version,
105
+ binName,
106
+ binPath,
107
+ url,
108
+ version,
153
109
  };
154
110
  }
155
111
 
@@ -161,66 +117,47 @@ function parsePackageJson() {
161
117
  *
162
118
  * See: https://docs.npmjs.com/files/package.json#bin
163
119
  */
164
- const INVALID_INPUT = 'Invalid inputs';
165
- function install(callback) {
166
- const options = parsePackageJson();
167
- if (!options) {
168
- throw new Error(INVALID_INPUT);
169
- }
120
+ export function installBinary() {
121
+ const options = loadConfiguration();
170
122
 
171
123
  fs.mkdirSync(options.binPath, { recursive: true });
172
124
  const ungz = zlib.createGunzip();
173
125
  const untar = tar.x({ cwd: options.binPath });
174
126
 
175
- // First we will Un-GZip, then we will untar. So once untar is completed,
176
- // binary is downloaded into `binPath`. Verify the binary and call it good
177
- untar.on('end', () => {
178
- verifyAndPlaceBinary(options.binName, options.binPath, callback);
179
- });
180
-
181
- console.log('Downloading from URL: ' + options.url);
182
-
183
- fetch(options.url).then((res) => {
184
- if (!res.ok) {
185
- throw new Error('Error downloading binary. HTTP Status Code: ' + res.status);
186
- }
187
-
188
- res.body.pipe(ungz).pipe(untar);
189
- });
190
- }
127
+ return new Promise((resolve, reject) => {
128
+ let settled = false;
129
+ const finish = (action, value) => {
130
+ if (settled) return;
131
+ settled = true;
132
+ action(value);
133
+ };
134
+
135
+ const handleError = (err) => finish(reject, err);
136
+ const handleSuccess = () => finish(resolve);
137
+
138
+ // First we will Un-GZip, then we will untar. So once untar is completed,
139
+ // binary is downloaded into `binPath`. Verify the binary and call it good
140
+ untar.on('end', () => {
141
+ try {
142
+ verifyAndPlaceBinary(options.binName, options.binPath);
143
+ handleSuccess();
144
+ } catch (err) {
145
+ handleError(err);
146
+ }
147
+ });
191
148
 
192
- function uninstall(callback) {
193
- const options = parsePackageJson();
149
+ ungz.on('error', handleError);
150
+ untar.on('error', handleError);
194
151
 
195
- getInstallationPath(function (err, installationPath) {
196
- if (err) {
197
- throw new Error('Error finding binary installation directory');
198
- }
152
+ fetch(options.url)
153
+ .then((res) => {
154
+ if (!res.ok) {
155
+ throw new Error('Error downloading binary. HTTP Status Code: ' + res.status);
156
+ }
199
157
 
200
- fs.unlinkSync(path.join(installationPath, options.binName));
201
- callback();
158
+ res.body.on('error', handleError);
159
+ res.body.pipe(ungz).pipe(untar);
160
+ })
161
+ .catch(handleError);
202
162
  });
203
163
  }
204
-
205
- const actions = {
206
- install: install,
207
- uninstall: uninstall,
208
- };
209
-
210
- const argv = process.argv;
211
- if (argv && argv.length > 2) {
212
- const cmd = process.argv[2];
213
- if (!actions[cmd]) {
214
- console.log('Invalid command to go-npm. `install` and `uninstall` are the only supported commands');
215
- process.exit(1);
216
- }
217
-
218
- try {
219
- actions[cmd](() => {
220
- process.exit(0);
221
- });
222
- } catch (err) {
223
- console.error(err);
224
- process.exit(1);
225
- }
226
- }