@fabr-client/core 0.1.4 → 0.1.6

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.
@@ -15,34 +15,145 @@ const packageByPlatform = {
15
15
  "darwin-arm64": "@fabr-client/core-darwin-arm64",
16
16
  };
17
17
 
18
- function resolvePlatformPackageBinary() {
19
- const pkg = packageByPlatform[platformDir];
20
- if (!pkg) {
21
- return null;
22
- }
23
- try {
24
- return path.join(path.dirname(require.resolve(`${pkg}/package.json`)), "bin", exe);
25
- } catch {
26
- return null;
27
- }
28
- }
29
-
30
- const candidates = [
31
- process.env.FABR_CLIENT_BIN,
32
- resolvePlatformPackageBinary(),
33
- // Local development fallback: package payloads staged next to this repo.
34
- path.join(__dirname, "..", "..", "npm-platforms", platformDir, "bin", exe),
35
- path.join(__dirname, platformDir, exe),
18
+ function resolvePlatformPackageBinary(pkg) {
19
+ if (!pkg) {
20
+ return null;
21
+ }
22
+ try {
23
+ return path.join(path.dirname(require.resolve(`${pkg}/package.json`)), "bin", exe);
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+
29
+ function npmCommand() {
30
+ const npmExecPath = process.env.npm_execpath;
31
+ if (npmExecPath) {
32
+ return { command: process.execPath, args: [npmExecPath] };
33
+ }
34
+ return {
35
+ command: platform === "win32" ? "npm.cmd" : "npm",
36
+ args: [],
37
+ };
38
+ }
39
+
40
+ function npmSpawnOptions(cwd) {
41
+ const npm = npmCommand();
42
+ return {
43
+ npm,
44
+ options: {
45
+ cwd,
46
+ env: process.env,
47
+ shell: platform === "win32" && npm.command.endsWith(".cmd"),
48
+ stdio: "inherit",
49
+ windowsHide: true,
50
+ },
51
+ };
52
+ }
53
+
54
+ function packageSpec(pkg) {
55
+ if (process.env.FABR_CLIENT_PLATFORM_PACKAGE_SPEC) {
56
+ return process.env.FABR_CLIENT_PLATFORM_PACKAGE_SPEC;
57
+ }
58
+ if (process.env.FABR_CLIENT_PLATFORM_PACKAGE_TARBALL) {
59
+ return process.env.FABR_CLIENT_PLATFORM_PACKAGE_TARBALL;
60
+ }
61
+
62
+ const ownPackage = require("../package.json");
63
+ const version = ownPackage.optionalDependencies?.[pkg] || ownPackage.version;
64
+ return `${pkg}@${version}`;
65
+ }
66
+
67
+ function runNpmInstall(label, args, cwd) {
68
+ const { npm, options } = npmSpawnOptions(cwd);
69
+ console.error(label);
70
+ const result = spawnSync(npm.command, [...npm.args, ...args], options);
71
+
72
+ if (result.error || result.status !== 0) {
73
+ const message = result.error ? result.error.message : `npm exited with status ${result.status}`;
74
+ console.error(`${label} failed: ${message}`);
75
+ return false;
76
+ }
77
+
78
+ return true;
79
+ }
80
+
81
+ function installPlatformPackageLocal(spec) {
82
+ return runNpmInstall(
83
+ `Installing Fabr Client native payload: ${spec}`,
84
+ [
85
+ "install",
86
+ spec,
87
+ "--no-save",
88
+ "--package-lock=false",
89
+ "--include=optional",
90
+ ],
91
+ path.join(__dirname, ".."),
92
+ );
93
+ }
94
+
95
+ function installPlatformPackageGlobal(spec) {
96
+ return runNpmInstall(
97
+ `Installing Fabr Client native payload globally: ${spec}`,
98
+ [
99
+ "install",
100
+ "-g",
101
+ spec,
102
+ "--include=optional",
103
+ ],
104
+ path.join(__dirname, ".."),
105
+ );
106
+ }
107
+
108
+ function resolveInstalledBinary(pkg) {
109
+ const binary = resolvePlatformPackageBinary(pkg);
110
+ return binary && fs.existsSync(binary) ? binary : null;
111
+ }
112
+
113
+ function installAndResolvePlatformPackage(pkg) {
114
+ if (!pkg || process.env.FABR_CLIENT_SKIP_PLATFORM_INSTALL === "1") {
115
+ return null;
116
+ }
117
+
118
+ const spec = packageSpec(pkg);
119
+ if (installPlatformPackageLocal(spec)) {
120
+ const binary = resolveInstalledBinary(pkg);
121
+ if (binary) {
122
+ return binary;
123
+ }
124
+ }
125
+
126
+ if (installPlatformPackageGlobal(spec)) {
127
+ const binary = resolveInstalledBinary(pkg);
128
+ if (binary) {
129
+ return binary;
130
+ }
131
+ }
132
+
133
+ return null;
134
+ }
135
+
136
+ const pkg = packageByPlatform[platformDir];
137
+ const candidates = [
138
+ process.env.FABR_CLIENT_BIN,
139
+ resolvePlatformPackageBinary(pkg),
140
+ // Local development fallback: package payloads staged next to this repo.
141
+ path.join(__dirname, "..", "..", "npm-platforms", platformDir, "bin", exe),
142
+ path.join(__dirname, platformDir, exe),
36
143
  path.join(__dirname, "..", platformDir, exe),
37
144
  path.join(__dirname, exe),
38
145
  ].filter(Boolean);
39
-
40
- const binary = candidates.find((candidate) => fs.existsSync(candidate));
41
-
146
+
147
+ let binary = candidates.find((candidate) => fs.existsSync(candidate));
148
+
149
+ if (!binary) {
150
+ binary = installAndResolvePlatformPackage(pkg);
151
+ }
152
+
42
153
  if (!binary) {
43
- const pkg = packageByPlatform[platformDir];
154
+ const spec = pkg ? packageSpec(pkg) : null;
44
155
  const installHint = pkg
45
- ? `Try: npm install -g ${pkg}`
156
+ ? `Try: npm install -g ${spec}`
46
157
  : "This platform is not currently supported by @fabr-client/core.";
47
158
  console.error(
48
159
  `Fabr Client does not include a binary for ${platformDir}.\n` +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabr-client/core",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Cross-platform launcher for Fabr Client",
5
5
  "license": "MIT",
6
6
  "homepage": "https://pivot.enclaws.com",
@@ -19,9 +19,9 @@
19
19
  "smoke": "node bin/fabr-client.js --help"
20
20
  },
21
21
  "optionalDependencies": {
22
- "@fabr-client/core-win32-x64": "0.1.4",
23
- "@fabr-client/core-darwin-x64": "0.1.4",
24
- "@fabr-client/core-darwin-arm64": "0.1.4"
22
+ "@fabr-client/core-win32-x64": "0.1.6",
23
+ "@fabr-client/core-darwin-x64": "0.1.6",
24
+ "@fabr-client/core-darwin-arm64": "0.1.6"
25
25
  },
26
26
  "files": [
27
27
  "bin/",
package/postinstall.js CHANGED
@@ -71,6 +71,7 @@ console.log(`Installing Fabr Client native payload: ${spec}`);
71
71
  const result = spawnSync(npm.command, args, {
72
72
  cwd: __dirname,
73
73
  env: process.env,
74
+ shell: platform === "win32" && npm.command.endsWith(".cmd"),
74
75
  stdio: "inherit",
75
76
  windowsHide: true,
76
77
  });