coder-config 0.40.16 → 0.41.2

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.
@@ -1,328 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Tauri Build Preparation Script
5
- *
6
- * Prepares the Node.js server bundle for Tauri packaging:
7
- * 1. Downloads Node.js binary for target platform
8
- * 2. Copies server files to bundle location
9
- * 3. Installs production dependencies
10
- */
11
-
12
- const fs = require('fs');
13
- const path = require('path');
14
- const https = require('https');
15
- const { spawnSync } = require('child_process');
16
- const os = require('os');
17
-
18
- const ROOT_DIR = path.join(__dirname, '..');
19
- const SRC_TAURI = path.join(ROOT_DIR, 'src-tauri');
20
- const BINARIES_DIR = path.join(SRC_TAURI, 'binaries');
21
- const SERVER_DIR = path.join(SRC_TAURI, 'server');
22
-
23
- // Node.js version to bundle (LTS)
24
- const NODE_VERSION = '20.18.1';
25
-
26
- // Target triple to Node.js platform mapping
27
- const TARGET_TO_NODE_PLATFORM = {
28
- 'aarch64-apple-darwin': 'darwin-arm64',
29
- 'x86_64-apple-darwin': 'darwin-x64',
30
- 'aarch64-pc-windows-msvc': 'win-arm64',
31
- 'x86_64-pc-windows-msvc': 'win-x64',
32
- 'aarch64-unknown-linux-gnu': 'linux-arm64',
33
- 'x86_64-unknown-linux-gnu': 'linux-x64',
34
- };
35
-
36
- // Parse --target argument from CLI
37
- function getTargetFromArgs() {
38
- const args = process.argv.slice(2);
39
- const targetIdx = args.indexOf('--target');
40
- if (targetIdx !== -1 && args[targetIdx + 1]) {
41
- return args[targetIdx + 1];
42
- }
43
- return null;
44
- }
45
-
46
- // Get target triple from env or args, fallback to host detection
47
- function getTauriTarget() {
48
- // Check command line --target
49
- const argTarget = getTargetFromArgs();
50
- if (argTarget) {
51
- console.log(`Using target from --target: ${argTarget}`);
52
- return argTarget;
53
- }
54
-
55
- // Check environment variables
56
- const envTarget = process.env.TAURI_TARGET || process.env.TARGET;
57
- if (envTarget) {
58
- console.log(`Using target from environment: ${envTarget}`);
59
- return envTarget;
60
- }
61
-
62
- // Fallback to host platform detection
63
- const platform = os.platform();
64
- const arch = os.arch();
65
-
66
- if (platform === 'darwin') {
67
- return arch === 'arm64' ? 'aarch64-apple-darwin' : 'x86_64-apple-darwin';
68
- } else if (platform === 'win32') {
69
- return arch === 'arm64' ? 'aarch64-pc-windows-msvc' : 'x86_64-pc-windows-msvc';
70
- } else if (platform === 'linux') {
71
- return arch === 'arm64' ? 'aarch64-unknown-linux-gnu' : 'x86_64-unknown-linux-gnu';
72
- }
73
-
74
- throw new Error(`Unsupported platform: ${platform}-${arch}`);
75
- }
76
-
77
- // Platform detection for Node.js download
78
- function getPlatform(tauriTarget) {
79
- const nodePlatform = TARGET_TO_NODE_PLATFORM[tauriTarget];
80
- if (!nodePlatform) {
81
- throw new Error(`Unknown target: ${tauriTarget}`);
82
- }
83
- return nodePlatform;
84
- }
85
-
86
- // Download a file
87
- async function downloadFile(url, dest) {
88
- return new Promise((resolve, reject) => {
89
- console.log(`Downloading: ${url}`);
90
-
91
- const file = fs.createWriteStream(dest);
92
-
93
- const request = (reqUrl) => {
94
- https.get(reqUrl, (response) => {
95
- if (response.statusCode === 302 || response.statusCode === 301) {
96
- // Follow redirect
97
- request(response.headers.location);
98
- return;
99
- }
100
-
101
- if (response.statusCode !== 200) {
102
- reject(new Error(`HTTP ${response.statusCode}: ${reqUrl}`));
103
- return;
104
- }
105
-
106
- const total = parseInt(response.headers['content-length'], 10);
107
- let downloaded = 0;
108
-
109
- response.on('data', (chunk) => {
110
- downloaded += chunk.length;
111
- if (total) {
112
- const pct = Math.round((downloaded / total) * 100);
113
- process.stdout.write(`\r Progress: ${pct}%`);
114
- }
115
- });
116
-
117
- response.pipe(file);
118
-
119
- file.on('finish', () => {
120
- file.close();
121
- console.log('\n Download complete');
122
- resolve();
123
- });
124
- }).on('error', (err) => {
125
- fs.unlink(dest, () => {});
126
- reject(err);
127
- });
128
- };
129
-
130
- request(url);
131
- });
132
- }
133
-
134
- // Extract tar.gz using spawn (safe from injection)
135
- function extractArchive(archivePath, destDir) {
136
- console.log(`Extracting to: ${destDir}`);
137
-
138
- // Use spawnSync with array arguments (safe from shell injection)
139
- const result = spawnSync('tar', ['-xzf', archivePath, '-C', destDir], {
140
- stdio: 'inherit'
141
- });
142
-
143
- if (result.status !== 0) {
144
- throw new Error(`Failed to extract archive: ${result.stderr || 'unknown error'}`);
145
- }
146
- }
147
-
148
- // Download Node.js binary
149
- async function downloadNode() {
150
- const tauriTarget = getTauriTarget();
151
- const platform = getPlatform(tauriTarget);
152
- const ext = platform.startsWith('win') ? 'zip' : 'tar.gz';
153
- const nodeDir = `node-v${NODE_VERSION}-${platform}`;
154
- const archiveName = `${nodeDir}.${ext}`;
155
- const url = `https://nodejs.org/dist/v${NODE_VERSION}/${archiveName}`;
156
-
157
- console.log(`\n=== Downloading Node.js ${NODE_VERSION} for ${platform} ===`);
158
-
159
- // Create directories
160
- if (!fs.existsSync(BINARIES_DIR)) {
161
- fs.mkdirSync(BINARIES_DIR, { recursive: true });
162
- }
163
-
164
- const archivePath = path.join(BINARIES_DIR, archiveName);
165
- const extractDir = BINARIES_DIR;
166
-
167
- // Download if not already present
168
- if (!fs.existsSync(archivePath)) {
169
- await downloadFile(url, archivePath);
170
- } else {
171
- console.log(' Archive already exists, skipping download');
172
- }
173
-
174
- // Extract
175
- extractArchive(archivePath, extractDir);
176
-
177
- // Move node binary to expected location with Tauri naming convention
178
- const sourceDir = path.join(extractDir, nodeDir);
179
- const isWindows = platform.startsWith('win');
180
- const sourceNode = path.join(sourceDir, isWindows ? 'node.exe' : 'bin/node');
181
-
182
- // Tauri sidecar naming: <name>-<target-triple>[.exe]
183
- const destNodeName = `node-server-${tauriTarget}${isWindows ? '.exe' : ''}`;
184
- const destNode = path.join(BINARIES_DIR, destNodeName);
185
-
186
- if (fs.existsSync(sourceNode)) {
187
- fs.copyFileSync(sourceNode, destNode);
188
- fs.chmodSync(destNode, 0o755);
189
- console.log(` Node binary copied to: ${destNodeName}`);
190
- }
191
-
192
- // Clean up extracted directory (keep archive for caching)
193
- fs.rmSync(sourceDir, { recursive: true, force: true });
194
-
195
- return destNode;
196
- }
197
-
198
- // Copy server files
199
- function copyServerFiles() {
200
- console.log('\n=== Copying server files ===');
201
-
202
- // Create server directory
203
- if (fs.existsSync(SERVER_DIR)) {
204
- fs.rmSync(SERVER_DIR, { recursive: true });
205
- }
206
- fs.mkdirSync(SERVER_DIR, { recursive: true });
207
-
208
- // Files to copy (individual files)
209
- const filesToCopy = [
210
- 'cli.js',
211
- 'config-loader.js',
212
- 'package.json',
213
- 'ui/server.cjs',
214
- 'ui/terminal-server.cjs',
215
- ];
216
-
217
- // Directories to copy (recursive)
218
- const dirsToCopy = [
219
- 'lib',
220
- 'ui/routes',
221
- 'ui/dist',
222
- 'shared',
223
- ];
224
-
225
- // Copy individual files
226
- for (const file of filesToCopy) {
227
- const src = path.join(ROOT_DIR, file);
228
- const dest = path.join(SERVER_DIR, file);
229
- if (fs.existsSync(src)) {
230
- // Ensure destination directory exists
231
- fs.mkdirSync(path.dirname(dest), { recursive: true });
232
- fs.copyFileSync(src, dest);
233
- console.log(` Copied: ${file}`);
234
- }
235
- }
236
-
237
- // Copy directories
238
- for (const dir of dirsToCopy) {
239
- const src = path.join(ROOT_DIR, dir);
240
- const dest = path.join(SERVER_DIR, dir);
241
- if (fs.existsSync(src)) {
242
- copyDirSync(src, dest);
243
- console.log(` Copied: ${dir}/`);
244
- }
245
- }
246
- }
247
-
248
- // Recursive directory copy
249
- function copyDirSync(src, dest) {
250
- fs.mkdirSync(dest, { recursive: true });
251
-
252
- const entries = fs.readdirSync(src, { withFileTypes: true });
253
-
254
- for (const entry of entries) {
255
- const srcPath = path.join(src, entry.name);
256
- const destPath = path.join(dest, entry.name);
257
-
258
- if (entry.isDirectory()) {
259
- copyDirSync(srcPath, destPath);
260
- } else {
261
- fs.copyFileSync(srcPath, destPath);
262
- }
263
- }
264
- }
265
-
266
- // Install production dependencies
267
- function installDependencies() {
268
- console.log('\n=== Installing production dependencies ===');
269
-
270
- const result = spawnSync('npm', ['install', '--production', '--ignore-scripts'], {
271
- cwd: SERVER_DIR,
272
- stdio: 'inherit',
273
- shell: true
274
- });
275
-
276
- if (result.status !== 0) {
277
- console.warn(' Warning: npm install may have had issues');
278
- }
279
-
280
- // Note: node-pty needs to be rebuilt for the target platform
281
- // This is handled by npm rebuild during the Tauri build
282
- console.log(' Dependencies installed');
283
- }
284
-
285
- // Create a wrapper script for the sidecar
286
- function createWrapperScript() {
287
- console.log('\n=== Creating wrapper script ===');
288
-
289
- const wrapperPath = path.join(SERVER_DIR, 'start-server.js');
290
- const wrapperContent = `#!/usr/bin/env node
291
- // Wrapper script to start the server
292
- // Used by Tauri sidecar
293
- process.chdir(__dirname);
294
- require('./cli.js');
295
- `;
296
-
297
- fs.writeFileSync(wrapperPath, wrapperContent);
298
- fs.chmodSync(wrapperPath, 0o755);
299
- console.log(' Wrapper script created');
300
- }
301
-
302
- // Main
303
- async function main() {
304
- console.log('=== Coder Config Tauri Build Preparation ===\n');
305
-
306
- try {
307
- // Check if we're building for distribution or just development
308
- const args = process.argv.slice(2);
309
- const skipNodeDownload = args.includes('--skip-node');
310
-
311
- if (!skipNodeDownload) {
312
- await downloadNode();
313
- }
314
-
315
- copyServerFiles();
316
- installDependencies();
317
- createWrapperScript();
318
-
319
- console.log('\n=== Build preparation complete! ===');
320
- console.log('Run `npm run tauri:build` to create the app bundle.');
321
-
322
- } catch (error) {
323
- console.error('Build preparation failed:', error);
324
- process.exit(1);
325
- }
326
- }
327
-
328
- main();