cc4-embedded-system 3.1.2 → 3.1.4

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.
Files changed (2) hide show
  1. package/dist/gui.js +66 -20
  2. package/package.json +1 -1
package/dist/gui.js CHANGED
@@ -59,11 +59,12 @@
59
59
  */
60
60
  import express from 'express';
61
61
  import open from 'open';
62
+ import fs from 'node:fs';
62
63
  import path from 'node:path';
63
64
  import { fileURLToPath } from 'node:url';
64
65
  import { runMakeFsData } from './makefsdata.js';
65
66
  import { getPackageVersion } from './utils.js';
66
- import { execSync } from 'node:child_process';
67
+ import { execFile } from 'node:child_process';
67
68
  import os from 'node:os';
68
69
  // prevent socket errors
69
70
  process.on('uncaughtException', (err) => {
@@ -85,7 +86,11 @@ if (portArgIndex !== -1 && process.argv[portArgIndex + 1]) {
85
86
  let server;
86
87
  let shutdownTimer = null;
87
88
  app.use(express.json());
88
- app.use(express.static(path.join(__dirname, '/public')));
89
+ const publicPath = fs.existsSync(path.join(__dirname, 'public'))
90
+ ? path.join(__dirname, 'public')
91
+ : path.join(__dirname, '../public');
92
+ console.log(`[System] Serving static files from: ${publicPath}`);
93
+ app.use(express.static(publicPath));
89
94
  const cancelShutdown = () => {
90
95
  if (shutdownTimer) {
91
96
  clearTimeout(shutdownTimer);
@@ -93,6 +98,29 @@ const cancelShutdown = () => {
93
98
  // console.log('🛡️ Shutdown cancelled (keep alive)');
94
99
  }
95
100
  };
101
+ const buildPowerShellArgs = (script) => {
102
+ const encodedCommand = Buffer.from(script, 'utf16le').toString('base64');
103
+ return [
104
+ '-NoProfile',
105
+ '-STA',
106
+ '-EncodedCommand',
107
+ encodedCommand
108
+ ];
109
+ };
110
+ const runDialogCommand = (command, args) => {
111
+ return new Promise((resolve, reject) => {
112
+ execFile(command, args, {
113
+ windowsHide: false,
114
+ maxBuffer: 1024 * 1024
115
+ }, (error, stdout, stderr) => {
116
+ if (error) {
117
+ reject(new Error(stderr.trim() || error.message));
118
+ return;
119
+ }
120
+ resolve(stdout.trim());
121
+ });
122
+ });
123
+ };
96
124
  app.get('/api/version', (_req, res) => {
97
125
  cancelShutdown();
98
126
  res.json({ version: getPackageVersion() });
@@ -168,30 +196,48 @@ app.post('/api/change-port', (req, res) => {
168
196
  }
169
197
  }, 100);
170
198
  });
171
- app.get('/api/browse', (req, res) => {
199
+ app.get('/api/browse', async (req, res) => {
200
+ cancelShutdown();
172
201
  const isDir = req.query.type === 'dir';
173
202
  const platform = os.platform();
174
- let command = '';
175
203
  try {
176
- if (platform === 'win32') { // Windows: Powershell + OpenFileDialog
177
- if (isDir)
178
- command = `powershell -Command "Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.OpenFileDialog; $f.CheckFileExists = $false; $f.CheckPathExists = $true; $f.FileName = 'Select Folder'; $f.ValidateNames = $false; if($f.ShowDialog() -eq 'OK'){ Split-Path $f.FileName }"`;
179
- else
180
- command = `powershell -Command "Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.OpenFileDialog; $f.Filter = 'C Files (*.c)|*.c|All Files (*.*)|*.*'; if($f.ShowDialog() -eq 'OK'){ $f.FileName }"`;
204
+ let result = '';
205
+ if (platform === 'win32') {
206
+ const script = isDir
207
+ ? [
208
+ 'Add-Type -AssemblyName System.Windows.Forms',
209
+ '$dialog = New-Object System.Windows.Forms.FolderBrowserDialog',
210
+ '$dialog.Description = "Select Input Directory"',
211
+ 'if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {',
212
+ ' $dialog.SelectedPath',
213
+ '}'
214
+ ].join('\n')
215
+ : [
216
+ 'Add-Type -AssemblyName System.Windows.Forms',
217
+ '$dialog = New-Object System.Windows.Forms.SaveFileDialog',
218
+ '$dialog.Filter = "C Files (*.c)|*.c|All Files (*.*)|*.*"',
219
+ '$dialog.DefaultExt = "c"',
220
+ '$dialog.AddExtension = $true',
221
+ '$dialog.OverwritePrompt = $true',
222
+ 'if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {',
223
+ ' $dialog.FileName',
224
+ '}'
225
+ ].join('\n');
226
+ result = await runDialogCommand('powershell.exe', buildPowerShellArgs(script));
181
227
  }
182
- else if (platform === 'darwin') { // macOS: darwin
183
- if (isDir)
184
- command = `osascript -e 'POSIX path of (choose folder with prompt "Select Input Directory")'`;
185
- else
186
- command = `osascript -e 'POSIX path of (choose file with prompt "Select Output File")'`;
228
+ else if (platform === 'darwin') {
229
+ result = await runDialogCommand('osascript', [
230
+ '-e',
231
+ isDir
232
+ ? 'POSIX path of (choose folder with prompt "Select Input Directory")'
233
+ : 'POSIX path of (choose file name with prompt "Select Output File")'
234
+ ]);
187
235
  }
188
- else { // Linux: Zenity
189
- if (isDir)
190
- command = `zenity --file-selection --directory --title="Select Input Directory"`;
191
- else
192
- command = `zenity --file-selection --title="Select Output File"`;
236
+ else {
237
+ result = await runDialogCommand('zenity', isDir
238
+ ? ['--file-selection', '--directory', '--title=Select Input Directory']
239
+ : ['--file-selection', '--save', '--confirm-overwrite', '--title=Select Output File', '--filename=fsdata.c']);
193
240
  }
194
- const result = execSync(command).toString().trim();
195
241
  res.json({ success: true, path: result || null });
196
242
  }
197
243
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc4-embedded-system",
3
- "version": "3.1.2",
3
+ "version": "3.1.4",
4
4
  "description": "A modern typescript version of makefsdata based on html-minifier-next and lwIP v1.3.1",
5
5
  "bin": {
6
6
  "cc4es": "./dist/gui.js"