@lynx-js/lynxtron-rebuild 0.0.1 → 0.0.3

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.
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { lynxtronRebuild } from '../lib/index.js';
4
+
5
+ function parseArgs() {
6
+ const args = process.argv.slice(2);
7
+ const options = {};
8
+
9
+ for (let i = 0; i < args.length; i++) {
10
+ if (args[i] === '--arch' && args[i + 1]) {
11
+ options.arch = args[i + 1];
12
+ i++;
13
+ } else if (args[i] === '--help') {
14
+ console.log('Usage: lynxtron-rebuild [options]');
15
+ console.log('');
16
+ console.log('Options:');
17
+ console.log(' --arch <architecture> Target architecture (e.g., x64, arm64, ia32)');
18
+ console.log(' Default: current system architecture');
19
+ console.log(' --help Show this help message');
20
+ process.exit(0);
21
+ }
22
+ }
23
+
24
+ return options;
25
+ }
26
+
27
+ async function main() {
28
+ try {
29
+ const options = parseArgs();
30
+ await lynxtronRebuild(options);
31
+ } catch (err) {
32
+ console.error('Error during rebuild:', err);
33
+ process.exit(1);
34
+ }
35
+ }
36
+
37
+ main();
package/lib/index.js ADDED
@@ -0,0 +1,176 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import https from 'node:https';
5
+ import { pipeline } from 'node:stream/promises';
6
+ import { spawn } from 'node:child_process';
7
+ import { zip } from 'compressing';
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+
12
+ const BASE_URL = 'https://github.com/lynx-family/lynxtron/releases/download/';
13
+
14
+ function getLynxtronVersion() {
15
+ let pkgPath;
16
+
17
+ try {
18
+ pkgPath = path.join(process.cwd(), 'node_modules', '@lynx-js', 'lynxtron', 'package.json');
19
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
20
+ return pkg.version;
21
+ } catch (e) {
22
+ try {
23
+ pkgPath = path.join(__dirname, '..', '..', '..', 'node_modules', '@lynx-js', 'lynxtron', 'package.json');
24
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
25
+ return pkg.version;
26
+ } catch (e2) {
27
+ throw new Error('Could not find @lynx-js/lynxtron package');
28
+ }
29
+ }
30
+ }
31
+
32
+ async function downloadFile(url, destPath) {
33
+ return new Promise((resolve, reject) => {
34
+ const file = fs.createWriteStream(destPath);
35
+ https.get(url, (response) => {
36
+ if (response.statusCode !== 200) {
37
+ fs.unlink(destPath, () => {});
38
+ reject(new Error(`Failed to download ${url}, status: ${response.statusCode}`));
39
+ return;
40
+ }
41
+ pipeline(response, file)
42
+ .then(resolve)
43
+ .catch(reject);
44
+ }).on('error', (err) => {
45
+ fs.unlink(destPath, () => {});
46
+ reject(err);
47
+ });
48
+ });
49
+ }
50
+
51
+ async function extractZip(zipPath, destDir) {
52
+ await zip.uncompress(zipPath, destDir);
53
+ }
54
+
55
+ async function downloadHeaders(version, distDir) {
56
+ const url = `${BASE_URL}v${version}/lynxtron-v${version}-node-headers.zip`;
57
+ const zipPath = path.join(distDir, `lynxtron-v${version}-node-headers.zip`);
58
+ const headersPath = path.join(distDir, `v${version}`);
59
+
60
+ if (fs.existsSync(headersPath)) {
61
+ console.log(`Headers already exist at ${headersPath}, skipping download`);
62
+ return headersPath;
63
+ }
64
+
65
+ if (!fs.existsSync(distDir)) {
66
+ fs.mkdirSync(distDir, { recursive: true });
67
+ }
68
+
69
+ console.log(`Downloading headers from ${url}`);
70
+ await downloadFile(url, zipPath);
71
+
72
+ console.log(`Extracting headers to ${distDir}`);
73
+ await extractZip(zipPath, distDir);
74
+
75
+ const extractedDir = path.join(distDir, 'node_headers');
76
+ if (fs.existsSync(extractedDir)) {
77
+ fs.renameSync(extractedDir, headersPath);
78
+ }
79
+
80
+ fs.unlinkSync(zipPath);
81
+
82
+ return headersPath;
83
+ }
84
+
85
+ function findModulesWithNativeCode(buildPath) {
86
+ const modules = [];
87
+ const nodeModulesPath = path.join(buildPath, 'node_modules');
88
+
89
+ if (!fs.existsSync(nodeModulesPath)) {
90
+ return modules;
91
+ }
92
+
93
+ const packages = fs.readdirSync(nodeModulesPath, { withFileTypes: true });
94
+
95
+ for (const pkg of packages) {
96
+ if (!pkg.isDirectory()) continue;
97
+ if (pkg.name.startsWith('.')) continue;
98
+
99
+ const pkgPath = path.join(nodeModulesPath, pkg.name);
100
+ const bindingGypPath = path.join(pkgPath, 'binding.gyp');
101
+
102
+ if (fs.existsSync(bindingGypPath)) {
103
+ modules.push(pkgPath);
104
+ }
105
+ }
106
+
107
+ return modules;
108
+ }
109
+
110
+ async function rebuildModule(modulePath, headersDir, electronVersion, arch) {
111
+ return new Promise((resolve, reject) => {
112
+ const args = [
113
+ 'rebuild',
114
+ `--target=${electronVersion}`,
115
+ '--runtime=electron',
116
+ `--arch=${arch}`,
117
+ '--build-from-source',
118
+ '--nodedir', headersDir
119
+ ];
120
+
121
+ console.log(`Rebuilding ${path.basename(modulePath)}...`);
122
+
123
+ const nodeGyp = spawn('npx', ['node-gyp', ...args], {
124
+ cwd: modulePath,
125
+ stdio: 'inherit'
126
+ });
127
+
128
+ nodeGyp.on('error', (err) => {
129
+ reject(err);
130
+ });
131
+
132
+ nodeGyp.on('close', (code) => {
133
+ if (code === 0) {
134
+ console.log(`Successfully rebuilt ${path.basename(modulePath)}`);
135
+ resolve();
136
+ } else {
137
+ reject(new Error(`node-gyp failed to rebuild ${path.basename(modulePath)} with exit code ${code}`));
138
+ }
139
+ });
140
+ });
141
+ }
142
+
143
+ export async function lynxtronRebuild(options = {}) {
144
+ const version = getLynxtronVersion();
145
+ console.log(`Detected Lynxtron version: ${version}`);
146
+
147
+ const arch = options.arch || process.arch;
148
+ console.log(`Using architecture: ${arch}`);
149
+
150
+ const distDir = path.join(__dirname, '..', 'dist');
151
+ const headersDir = await downloadHeaders(version, distDir);
152
+
153
+ console.log(`Headers downloaded to: ${headersDir}`);
154
+
155
+ const buildPath = options.buildPath || process.cwd();
156
+ const modules = findModulesWithNativeCode(buildPath);
157
+
158
+ if (modules.length === 0) {
159
+ console.log('No native modules found to rebuild');
160
+ return;
161
+ }
162
+
163
+ console.log(`Found ${modules.length} native module(s) to rebuild:`);
164
+ modules.forEach(m => console.log(` - ${path.basename(m)}`));
165
+
166
+ for (const modulePath of modules) {
167
+ try {
168
+ await rebuildModule(modulePath, headersDir, version, arch);
169
+ } catch (err) {
170
+ console.error(`Error rebuilding ${path.basename(modulePath)}: ${err.message}`);
171
+ throw err;
172
+ }
173
+ }
174
+
175
+ console.log('Rebuild completed successfully!');
176
+ }
package/package.json CHANGED
@@ -1,8 +1,24 @@
1
1
  {
2
2
  "name": "@lynx-js/lynxtron-rebuild",
3
- "version": "0.0.1",
4
- "description": "Lynxtron native module rebuild tool",
5
- "keywords": ["lynx", "lynxtron", "rebuild", "native"],
3
+ "version": "0.0.3",
4
+ "description": "Rebuild native modules for Lynxtron",
5
+ "main": "lib/index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/lynx-family/lynxtron.git"
9
+ },
10
+ "bin": {
11
+ "lynxtron-rebuild": "bin/lynxtron-rebuild.js"
12
+ },
13
+ "type": "module",
14
+ "keywords": [
15
+ "lynxtron",
16
+ "rebuild"
17
+ ],
6
18
  "author": "",
7
- "license": "MIT"
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "compressing": "^1.10.0",
22
+ "node-gyp": "^12.2.0"
23
+ }
8
24
  }