sphere-cli 0.1.41 → 0.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/sphere.js +19 -664
- package/package.json +6 -13
- package/scripts/postinstall.js +82 -69
- package/examples/nhanes_sample.csv +0 -4900
- package/scripts/certify.py +0 -131
- package/scripts/evaluate.py +0 -70
- package/sphere-node.js +0 -7
- package/sphere_cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/sphere_cli/__pycache__/__init__.cpython-314.pyc +0 -0
- package/sphere_cli/__pycache__/_algo._givens_inplace_nb-84.py314.1.nbc +0 -0
- package/sphere_cli/__pycache__/_algo._givens_inplace_nb-84.py314.nbi +0 -0
- package/sphere_cli/__pycache__/_algo.cpython-312.pyc +0 -0
- package/sphere_cli/__pycache__/_core.cpython-312.pyc +0 -0
- package/sphere_cli/__pycache__/_evaluate.cpython-312.pyc +0 -0
- package/sphere_cli/__pycache__/_evaluate.cpython-314.pyc +0 -0
- package/sphere_cli/__pycache__/_generate.cpython-312.pyc +0 -0
- package/sphere_cli/__pycache__/_generate.cpython-314.pyc +0 -0
- package/sphere_cli/__pycache__/cli.cpython-312.pyc +0 -0
- package/sphere_cli/__pycache__/cli.cpython-314.pyc +0 -0
- package/sphere_cli/_algo.cpython-314-darwin.so +0 -0
- package/sphere_cli/_certify.cpython-314-darwin.so +0 -0
- package/sphere_cli/_core.cpython-314-darwin.so +0 -0
- package/sphere_cli/_evaluate.cpython-314-darwin.so +0 -0
- package/sphere_cli/_generate.cpython-314-darwin.so +0 -0
- package/sphere_cli/cli.cpython-314-darwin.so +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sphere-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "SPHERE CLI — synthetic data generation, evaluation, and certification",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "SPHERE CLI — synthetic data generation, evaluation, and certification (sealed native binary)",
|
|
5
5
|
"keywords": ["synthetic-data", "privacy", "cli", "data-science"],
|
|
6
6
|
"homepage": "https://github.com/statzihuai/sphere-cli",
|
|
7
7
|
"bugs": "https://github.com/statzihuai/sphere-cli/issues",
|
|
@@ -14,19 +14,12 @@
|
|
|
14
14
|
"sphere": "bin/sphere.js"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"postinstall": "node scripts/postinstall.js"
|
|
18
|
-
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"bytenode": "^1.5.7"
|
|
17
|
+
"postinstall": "node scripts/postinstall.js",
|
|
18
|
+
"release": "bash scripts/release.sh"
|
|
21
19
|
},
|
|
22
20
|
"files": [
|
|
23
|
-
"bin/",
|
|
24
|
-
"
|
|
25
|
-
"scripts/postinstall.js",
|
|
26
|
-
"scripts/evaluate.py",
|
|
27
|
-
"scripts/certify.py",
|
|
28
|
-
"sphere_cli/",
|
|
29
|
-
"sphere-node.js"
|
|
21
|
+
"bin/sphere.js",
|
|
22
|
+
"scripts/postinstall.js"
|
|
30
23
|
],
|
|
31
24
|
"engines": {
|
|
32
25
|
"node": ">=18.0.0"
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,93 +1,106 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* SPHERE CLI postinstall —
|
|
4
|
+
* SPHERE CLI postinstall — download the platform-specific sealed binary.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* The SPHERE engine ships as a signed + notarized native binary (one per
|
|
7
|
+
* platform) hosted on GitHub Releases. This script detects the platform,
|
|
8
|
+
* downloads the matching tarball, verifies its SHA-256 against the published
|
|
9
|
+
* SHA256SUMS.txt, and extracts it into ./vendor/. No algorithm source ships in
|
|
10
|
+
* the npm package — only this downloader + a thin launcher.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* Env:
|
|
13
|
+
* SPHERE_SKIP_POSTINSTALL=1 skip download (CI / offline)
|
|
14
|
+
* SPHERE_BINARY_BASEURL=... override the release base URL (testing)
|
|
13
15
|
*/
|
|
14
16
|
|
|
17
|
+
const fs = require('fs');
|
|
15
18
|
const path = require('path');
|
|
16
|
-
const
|
|
19
|
+
const crypto = require('crypto');
|
|
20
|
+
const { execFileSync } = require('child_process');
|
|
17
21
|
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const PKG = require('../package.json');
|
|
23
|
+
const VERSION = PKG.version;
|
|
24
|
+
const REPO = 'statzihuai/sphere-cli';
|
|
25
|
+
|
|
26
|
+
const PLATFORM = process.platform; // 'darwin' | 'linux'
|
|
27
|
+
const ARCH = process.arch; // 'arm64' | 'x64'
|
|
28
|
+
const KEY = `${PLATFORM}-${ARCH}`;
|
|
29
|
+
const SUPPORTED = new Set(['darwin-arm64', 'darwin-x64', 'linux-x64']);
|
|
30
|
+
|
|
31
|
+
const PKG_ROOT = path.join(__dirname, '..');
|
|
32
|
+
const VENDOR = path.join(PKG_ROOT, 'vendor');
|
|
33
|
+
const ASSET = `sphere-${KEY}.tar.gz`;
|
|
34
|
+
const BASE = process.env.SPHERE_BINARY_BASEURL
|
|
35
|
+
|| `https://github.com/${REPO}/releases/download/v${VERSION}`;
|
|
36
|
+
|
|
37
|
+
function log(m) { process.stdout.write(`sphere-cli: ${m}\n`); }
|
|
38
|
+
function fail(m) { process.stderr.write(`sphere-cli: ${m}\n`); process.exit(1); }
|
|
24
39
|
|
|
25
|
-
// ── Skip flag ─────────────────────────────────────────────────────────────────
|
|
26
40
|
if (process.env.SPHERE_SKIP_POSTINSTALL === '1') {
|
|
27
|
-
|
|
41
|
+
log('SPHERE_SKIP_POSTINSTALL=1 — skipping binary download.');
|
|
28
42
|
process.exit(0);
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
process.stdout.write(`✓ SPHERE algorithm already compiled for v${VERSION}.\n`);
|
|
45
|
+
if (!SUPPORTED.has(KEY)) {
|
|
46
|
+
// Don't hard-fail the install; the launcher prints guidance if run.
|
|
47
|
+
process.stderr.write(
|
|
48
|
+
`sphere-cli: no prebuilt binary for ${KEY} yet ` +
|
|
49
|
+
`(supported: ${[...SUPPORTED].join(', ')}).\n`,
|
|
50
|
+
);
|
|
38
51
|
process.exit(0);
|
|
39
52
|
}
|
|
40
53
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
// Already installed for this version?
|
|
55
|
+
const STAMP = path.join(VENDOR, '.version');
|
|
56
|
+
const BIN = path.join(VENDOR, 'sphere-cli', 'sphere');
|
|
57
|
+
if (fs.existsSync(BIN) && fs.existsSync(STAMP) &&
|
|
58
|
+
fs.readFileSync(STAMP, 'utf8').trim() === VERSION) {
|
|
59
|
+
log(`binary already present for v${VERSION}.`);
|
|
60
|
+
process.exit(0);
|
|
45
61
|
}
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (fs.existsSync(OUT)) {
|
|
51
|
-
process.stdout.write('✓ SPHERE algorithm already compiled.\n');
|
|
52
|
-
process.exit(0);
|
|
53
|
-
}
|
|
54
|
-
process.stderr.write('sphere-node.js is a stub but sphere-node.jsc is missing. Reinstall sphere-cli.\n');
|
|
55
|
-
process.exit(1);
|
|
63
|
+
function curl(url, dest) {
|
|
64
|
+
execFileSync('curl', ['-fL', '--retry', '3', '--retry-delay', '2',
|
|
65
|
+
'--connect-timeout', '30', '-o', dest, url], { stdio: ['ignore', 'ignore', 'inherit'] });
|
|
56
66
|
}
|
|
57
67
|
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
function sha256(file) {
|
|
69
|
+
const h = crypto.createHash('sha256');
|
|
70
|
+
h.update(fs.readFileSync(file));
|
|
71
|
+
return h.digest('hex');
|
|
72
|
+
}
|
|
60
73
|
|
|
61
|
-
let bytenode;
|
|
62
74
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
);
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
75
|
+
fs.mkdirSync(VENDOR, { recursive: true });
|
|
76
|
+
const tarball = path.join(VENDOR, ASSET);
|
|
77
|
+
|
|
78
|
+
log(`downloading ${ASSET} (v${VERSION}) …`);
|
|
79
|
+
curl(`${BASE}/${ASSET}`, tarball);
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
81
|
+
// Verify checksum against the published SHA256SUMS.txt
|
|
82
|
+
const sumsFile = path.join(VENDOR, 'SHA256SUMS.txt');
|
|
83
|
+
curl(`${BASE}/SHA256SUMS.txt`, sumsFile);
|
|
84
|
+
const sums = fs.readFileSync(sumsFile, 'utf8');
|
|
85
|
+
const expected = sums.split('\n')
|
|
86
|
+
.map((l) => l.trim().split(/\s+/))
|
|
87
|
+
.find((p) => p[1] && p[1].endsWith(ASSET));
|
|
88
|
+
if (!expected) fail(`no checksum for ${ASSET} in SHA256SUMS.txt`);
|
|
89
|
+
const got = sha256(tarball);
|
|
90
|
+
if (got !== expected[0]) {
|
|
91
|
+
fail(`checksum mismatch for ${ASSET}\n expected ${expected[0]}\n got ${got}`);
|
|
92
|
+
}
|
|
93
|
+
log('checksum verified ✓');
|
|
94
|
+
|
|
95
|
+
// Extract
|
|
96
|
+
fs.rmSync(path.join(VENDOR, 'sphere-cli'), { recursive: true, force: true });
|
|
97
|
+
execFileSync('tar', ['-xzf', tarball, '-C', VENDOR], { stdio: 'inherit' });
|
|
98
|
+
fs.chmodSync(BIN, 0o755);
|
|
99
|
+
fs.unlinkSync(tarball);
|
|
100
|
+
fs.writeFileSync(STAMP, VERSION);
|
|
101
|
+
|
|
102
|
+
log(`installed sealed binary for ${KEY} ✓`);
|
|
103
|
+
} catch (e) {
|
|
104
|
+
fail(`failed to install binary: ${e.message}\n` +
|
|
105
|
+
`You can retry with: npm rebuild sphere-cli`);
|
|
106
|
+
}
|