@synsci/openscience 1.2.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/bin/bin/openscience +116 -0
- package/bin/openscience +116 -0
- package/package.json +24 -0
- package/postinstall.mjs +133 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const childProcess = require("child_process")
|
|
4
|
+
const fs = require("fs")
|
|
5
|
+
const path = require("path")
|
|
6
|
+
const os = require("os")
|
|
7
|
+
|
|
8
|
+
function run(target) {
|
|
9
|
+
// Clean up files that confuse Bun compiled binaries.
|
|
10
|
+
// Install dir stays as ~/.openscience/ until the path-migration follow-up PR.
|
|
11
|
+
const openscienceDir = path.join(os.homedir(), ".openscience")
|
|
12
|
+
for (const poison of ["package.json", ".gitignore", "bun.lockb", "bunfig.toml"]) {
|
|
13
|
+
try { fs.unlinkSync(path.join(openscienceDir, poison)) } catch {}
|
|
14
|
+
}
|
|
15
|
+
try { fs.rmSync(path.join(openscienceDir, "node_modules"), { recursive: true }) } catch {}
|
|
16
|
+
// Clear macOS extended attributes that cause Bun binaries to hang
|
|
17
|
+
if (os.platform() === "darwin") {
|
|
18
|
+
try { childProcess.spawnSync("xattr", ["-rc", openscienceDir], { stdio: "ignore" }) } catch {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const result = childProcess.spawnSync(target, process.argv.slice(2), {
|
|
22
|
+
stdio: "inherit",
|
|
23
|
+
})
|
|
24
|
+
if (result.error) {
|
|
25
|
+
console.error(result.error.message)
|
|
26
|
+
process.exit(1)
|
|
27
|
+
}
|
|
28
|
+
const code = typeof result.status === "number" ? result.status : 0
|
|
29
|
+
process.exit(code)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Helper: check if a path points to a real binary (not this wrapper script)
|
|
33
|
+
function isBinary(p) {
|
|
34
|
+
try {
|
|
35
|
+
if (!fs.existsSync(p)) return false
|
|
36
|
+
const real = fs.realpathSync(p)
|
|
37
|
+
// Skip if it resolves to this script (self-reference via symlink)
|
|
38
|
+
if (real === fs.realpathSync(__filename)) return false
|
|
39
|
+
// Skip if it's a .js file (another wrapper)
|
|
40
|
+
if (real.endsWith(".js")) return false
|
|
41
|
+
return true
|
|
42
|
+
} catch {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 1. Check OPENSCIENCE_BIN_PATH env var
|
|
48
|
+
const envPath = process.env.OPENSCIENCE_BIN_PATH
|
|
49
|
+
if (envPath && isBinary(envPath)) {
|
|
50
|
+
run(envPath)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const binary = os.platform() === "win32" ? "openscience.exe" : "openscience"
|
|
54
|
+
const scriptPath = fs.realpathSync(__filename)
|
|
55
|
+
const scriptDir = path.dirname(scriptPath)
|
|
56
|
+
|
|
57
|
+
const platformMap = { darwin: "darwin", linux: "linux", win32: "windows" }
|
|
58
|
+
const archMap = { x64: "x64", arm64: "arm64", arm: "arm" }
|
|
59
|
+
const platform = platformMap[os.platform()] || os.platform()
|
|
60
|
+
const arch = archMap[os.arch()] || os.arch()
|
|
61
|
+
const base = "openscience-" + platform + "-" + arch
|
|
62
|
+
const scopedBase = "cli-" + platform + "-" + arch
|
|
63
|
+
|
|
64
|
+
// 2. Search this install's node_modules for the matching platform package.
|
|
65
|
+
// This must come before ~/.openscience or Homebrew fallbacks; otherwise an npm
|
|
66
|
+
// install can accidentally launch an older globally-installed binary.
|
|
67
|
+
let current = scriptDir
|
|
68
|
+
while (true) {
|
|
69
|
+
const modules = path.join(current, "node_modules")
|
|
70
|
+
if (fs.existsSync(modules)) {
|
|
71
|
+
try {
|
|
72
|
+
const entries = fs.readdirSync(modules)
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
if (entry.startsWith(base)) {
|
|
75
|
+
const candidate = path.join(modules, entry, "bin", binary)
|
|
76
|
+
if (isBinary(candidate)) run(candidate)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check scoped packages (@synsci/openscience-darwin-arm64)
|
|
80
|
+
const scoped = path.join(modules, "@openscience")
|
|
81
|
+
if (fs.existsSync(scoped)) {
|
|
82
|
+
const scopedEntries = fs.readdirSync(scoped)
|
|
83
|
+
for (const entry of scopedEntries) {
|
|
84
|
+
if (entry.startsWith(scopedBase)) {
|
|
85
|
+
const candidate = path.join(scoped, entry, "bin", binary)
|
|
86
|
+
if (isBinary(candidate)) run(candidate)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {}
|
|
91
|
+
}
|
|
92
|
+
const parent = path.dirname(current)
|
|
93
|
+
if (parent === current) break
|
|
94
|
+
current = parent
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 3. Check ~/.openscience/bin (curl installer fallback; dir renamed later)
|
|
98
|
+
const homeBin = path.join(os.homedir(), ".openscience", "bin", binary)
|
|
99
|
+
if (isBinary(homeBin)) {
|
|
100
|
+
run(homeBin)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 4. Check /opt/homebrew/bin (macOS)
|
|
104
|
+
if (os.platform() === "darwin" && isBinary("/opt/homebrew/bin/openscience")) {
|
|
105
|
+
run("/opt/homebrew/bin/openscience")
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 5. Check /usr/local/bin
|
|
109
|
+
if (isBinary("/usr/local/bin/openscience")) {
|
|
110
|
+
run("/usr/local/bin/openscience")
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.error("openscience binary not found.")
|
|
114
|
+
console.error("Install with: curl -fsSL https://syntheticsciences.ai/install | bash")
|
|
115
|
+
console.error("Or set OPENSCIENCE_BIN_PATH environment variable.")
|
|
116
|
+
process.exit(1)
|
package/bin/openscience
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const childProcess = require("child_process")
|
|
4
|
+
const fs = require("fs")
|
|
5
|
+
const path = require("path")
|
|
6
|
+
const os = require("os")
|
|
7
|
+
|
|
8
|
+
function run(target) {
|
|
9
|
+
// Clean up files that confuse Bun compiled binaries.
|
|
10
|
+
// Install dir stays as ~/.openscience/ until the path-migration follow-up PR.
|
|
11
|
+
const openscienceDir = path.join(os.homedir(), ".openscience")
|
|
12
|
+
for (const poison of ["package.json", ".gitignore", "bun.lockb", "bunfig.toml"]) {
|
|
13
|
+
try { fs.unlinkSync(path.join(openscienceDir, poison)) } catch {}
|
|
14
|
+
}
|
|
15
|
+
try { fs.rmSync(path.join(openscienceDir, "node_modules"), { recursive: true }) } catch {}
|
|
16
|
+
// Clear macOS extended attributes that cause Bun binaries to hang
|
|
17
|
+
if (os.platform() === "darwin") {
|
|
18
|
+
try { childProcess.spawnSync("xattr", ["-rc", openscienceDir], { stdio: "ignore" }) } catch {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const result = childProcess.spawnSync(target, process.argv.slice(2), {
|
|
22
|
+
stdio: "inherit",
|
|
23
|
+
})
|
|
24
|
+
if (result.error) {
|
|
25
|
+
console.error(result.error.message)
|
|
26
|
+
process.exit(1)
|
|
27
|
+
}
|
|
28
|
+
const code = typeof result.status === "number" ? result.status : 0
|
|
29
|
+
process.exit(code)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Helper: check if a path points to a real binary (not this wrapper script)
|
|
33
|
+
function isBinary(p) {
|
|
34
|
+
try {
|
|
35
|
+
if (!fs.existsSync(p)) return false
|
|
36
|
+
const real = fs.realpathSync(p)
|
|
37
|
+
// Skip if it resolves to this script (self-reference via symlink)
|
|
38
|
+
if (real === fs.realpathSync(__filename)) return false
|
|
39
|
+
// Skip if it's a .js file (another wrapper)
|
|
40
|
+
if (real.endsWith(".js")) return false
|
|
41
|
+
return true
|
|
42
|
+
} catch {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 1. Check OPENSCIENCE_BIN_PATH env var
|
|
48
|
+
const envPath = process.env.OPENSCIENCE_BIN_PATH
|
|
49
|
+
if (envPath && isBinary(envPath)) {
|
|
50
|
+
run(envPath)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const binary = os.platform() === "win32" ? "openscience.exe" : "openscience"
|
|
54
|
+
const scriptPath = fs.realpathSync(__filename)
|
|
55
|
+
const scriptDir = path.dirname(scriptPath)
|
|
56
|
+
|
|
57
|
+
const platformMap = { darwin: "darwin", linux: "linux", win32: "windows" }
|
|
58
|
+
const archMap = { x64: "x64", arm64: "arm64", arm: "arm" }
|
|
59
|
+
const platform = platformMap[os.platform()] || os.platform()
|
|
60
|
+
const arch = archMap[os.arch()] || os.arch()
|
|
61
|
+
const base = "openscience-" + platform + "-" + arch
|
|
62
|
+
const scopedBase = "cli-" + platform + "-" + arch
|
|
63
|
+
|
|
64
|
+
// 2. Search this install's node_modules for the matching platform package.
|
|
65
|
+
// This must come before ~/.openscience or Homebrew fallbacks; otherwise an npm
|
|
66
|
+
// install can accidentally launch an older globally-installed binary.
|
|
67
|
+
let current = scriptDir
|
|
68
|
+
while (true) {
|
|
69
|
+
const modules = path.join(current, "node_modules")
|
|
70
|
+
if (fs.existsSync(modules)) {
|
|
71
|
+
try {
|
|
72
|
+
const entries = fs.readdirSync(modules)
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
if (entry.startsWith(base)) {
|
|
75
|
+
const candidate = path.join(modules, entry, "bin", binary)
|
|
76
|
+
if (isBinary(candidate)) run(candidate)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check scoped packages (@synsci/openscience-darwin-arm64)
|
|
80
|
+
const scoped = path.join(modules, "@openscience")
|
|
81
|
+
if (fs.existsSync(scoped)) {
|
|
82
|
+
const scopedEntries = fs.readdirSync(scoped)
|
|
83
|
+
for (const entry of scopedEntries) {
|
|
84
|
+
if (entry.startsWith(scopedBase)) {
|
|
85
|
+
const candidate = path.join(scoped, entry, "bin", binary)
|
|
86
|
+
if (isBinary(candidate)) run(candidate)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {}
|
|
91
|
+
}
|
|
92
|
+
const parent = path.dirname(current)
|
|
93
|
+
if (parent === current) break
|
|
94
|
+
current = parent
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 3. Check ~/.openscience/bin (curl installer fallback; dir renamed later)
|
|
98
|
+
const homeBin = path.join(os.homedir(), ".openscience", "bin", binary)
|
|
99
|
+
if (isBinary(homeBin)) {
|
|
100
|
+
run(homeBin)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 4. Check /opt/homebrew/bin (macOS)
|
|
104
|
+
if (os.platform() === "darwin" && isBinary("/opt/homebrew/bin/openscience")) {
|
|
105
|
+
run("/opt/homebrew/bin/openscience")
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 5. Check /usr/local/bin
|
|
109
|
+
if (isBinary("/usr/local/bin/openscience")) {
|
|
110
|
+
run("/usr/local/bin/openscience")
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.error("openscience binary not found.")
|
|
114
|
+
console.error("Install with: curl -fsSL https://syntheticsciences.ai/install | bash")
|
|
115
|
+
console.error("Or set OPENSCIENCE_BIN_PATH environment variable.")
|
|
116
|
+
process.exit(1)
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@synsci/openscience",
|
|
3
|
+
"bin": {
|
|
4
|
+
"openscience": "./bin/openscience"
|
|
5
|
+
},
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "bun ./postinstall.mjs || node ./postinstall.mjs"
|
|
8
|
+
},
|
|
9
|
+
"version": "1.2.0",
|
|
10
|
+
"optionalDependencies": {
|
|
11
|
+
"@synsci/openscience-linux-x64-baseline-musl": "1.2.0",
|
|
12
|
+
"@synsci/openscience-windows-x64-baseline": "1.2.0",
|
|
13
|
+
"@synsci/openscience-linux-x64-baseline": "1.2.0",
|
|
14
|
+
"@synsci/openscience-darwin-x64": "1.2.0",
|
|
15
|
+
"@synsci/openscience-linux-arm64-musl": "1.2.0",
|
|
16
|
+
"@synsci/openscience-darwin-x64-baseline": "1.2.0",
|
|
17
|
+
"@synsci/openscience": "1.2.0",
|
|
18
|
+
"@synsci/openscience-linux-x64-musl": "1.2.0",
|
|
19
|
+
"@synsci/openscience-darwin-arm64": "1.2.0",
|
|
20
|
+
"@synsci/openscience-linux-arm64": "1.2.0",
|
|
21
|
+
"@synsci/openscience-windows-x64": "1.2.0",
|
|
22
|
+
"@synsci/openscience-linux-x64": "1.2.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/postinstall.mjs
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import os from "os"
|
|
6
|
+
import { fileURLToPath } from "url"
|
|
7
|
+
import { createRequire } from "module"
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
10
|
+
const require = createRequire(import.meta.url)
|
|
11
|
+
|
|
12
|
+
function detectPlatformAndArch() {
|
|
13
|
+
// Map platform names
|
|
14
|
+
let platform
|
|
15
|
+
switch (os.platform()) {
|
|
16
|
+
case "darwin":
|
|
17
|
+
platform = "darwin"
|
|
18
|
+
break
|
|
19
|
+
case "linux":
|
|
20
|
+
platform = "linux"
|
|
21
|
+
break
|
|
22
|
+
case "win32":
|
|
23
|
+
platform = "windows"
|
|
24
|
+
break
|
|
25
|
+
default:
|
|
26
|
+
platform = os.platform()
|
|
27
|
+
break
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Map architecture names
|
|
31
|
+
let arch
|
|
32
|
+
switch (os.arch()) {
|
|
33
|
+
case "x64":
|
|
34
|
+
arch = "x64"
|
|
35
|
+
break
|
|
36
|
+
case "arm64":
|
|
37
|
+
arch = "arm64"
|
|
38
|
+
break
|
|
39
|
+
case "arm":
|
|
40
|
+
arch = "arm"
|
|
41
|
+
break
|
|
42
|
+
default:
|
|
43
|
+
arch = os.arch()
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { platform, arch }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function findBinary() {
|
|
51
|
+
const { platform, arch } = detectPlatformAndArch()
|
|
52
|
+
const binaryName = platform === "windows" ? "openscience.exe" : "openscience"
|
|
53
|
+
|
|
54
|
+
// Try scoped package first (@synsci/openscience-darwin-arm64), then unscoped (openscience-darwin-arm64)
|
|
55
|
+
const packageNames = [
|
|
56
|
+
`@synsci/openscience-${platform}-${arch}`,
|
|
57
|
+
`openscience-${platform}-${arch}`,
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
for (const packageName of packageNames) {
|
|
61
|
+
try {
|
|
62
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
63
|
+
const packageDir = path.dirname(packageJsonPath)
|
|
64
|
+
const binaryPath = path.join(packageDir, "bin", binaryName)
|
|
65
|
+
|
|
66
|
+
if (!fs.existsSync(binaryPath)) {
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { binaryPath, binaryName }
|
|
71
|
+
} catch {
|
|
72
|
+
continue
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
throw new Error(`Could not find platform binary package for ${platform}-${arch}`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function prepareBinDirectory(binaryName) {
|
|
80
|
+
const binDir = path.join(__dirname, "bin")
|
|
81
|
+
const targetPath = path.join(binDir, binaryName)
|
|
82
|
+
|
|
83
|
+
// Ensure bin directory exists
|
|
84
|
+
if (!fs.existsSync(binDir)) {
|
|
85
|
+
fs.mkdirSync(binDir, { recursive: true })
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Remove existing binary/symlink if it exists
|
|
89
|
+
if (fs.existsSync(targetPath)) {
|
|
90
|
+
fs.unlinkSync(targetPath)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { binDir, targetPath }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function symlinkBinary(sourcePath, binaryName) {
|
|
97
|
+
const { targetPath } = prepareBinDirectory(binaryName)
|
|
98
|
+
|
|
99
|
+
fs.symlinkSync(sourcePath, targetPath)
|
|
100
|
+
console.log(`openscience binary symlinked: ${targetPath} -> ${sourcePath}`)
|
|
101
|
+
|
|
102
|
+
// Verify the file exists after operation
|
|
103
|
+
if (!fs.existsSync(targetPath)) {
|
|
104
|
+
throw new Error(`Failed to symlink binary to ${targetPath}`)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function main() {
|
|
109
|
+
try {
|
|
110
|
+
if (os.platform() === "win32") {
|
|
111
|
+
// On Windows, the .exe is already included in the package and bin field points to it
|
|
112
|
+
// No postinstall setup needed
|
|
113
|
+
console.log("Windows detected: binary setup not needed (using packaged .exe)")
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// On non-Windows platforms, just verify the binary package exists
|
|
118
|
+
// Don't replace the wrapper script - it handles binary execution
|
|
119
|
+
const { binaryPath } = findBinary()
|
|
120
|
+
console.log(`Platform binary verified at: ${binaryPath}`)
|
|
121
|
+
console.log("Wrapper script will handle binary execution")
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error("Failed to setup openscience binary:", error.message)
|
|
124
|
+
process.exit(1)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
main()
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error("Postinstall script error:", error.message)
|
|
132
|
+
process.exit(0)
|
|
133
|
+
}
|