structscript 1.3.0 → 1.4.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.
@@ -33,10 +33,17 @@ const HELP = `
33
33
  ${BANNER}
34
34
  ${t(C.bold, 'USAGE')}
35
35
  ${t(C.lime, 'structscript')} ${t(C.teal, '<file.ss>')} Run a .ss file
36
+ ${t(C.lime, 'structscript')} ${t(C.teal, 'editor')} Open the visual editor (IDE)
37
+ ${t(C.lime, 'structscript')} ${t(C.teal, 'editor <file.ss>')} Open a file in the editor
36
38
  ${t(C.lime, 'structscript')} ${t(C.teal, 'repl')} Start interactive REPL
37
39
  ${t(C.lime, 'structscript')} ${t(C.teal, 'run <file.ss>')} Run a .ss file (explicit)
38
40
  ${t(C.lime, 'structscript')} ${t(C.teal, 'check <file.ss>')} Check syntax without running
39
41
  ${t(C.lime, 'structscript')} ${t(C.teal, 'version')} Show version info
42
+
43
+ ${t(C.bold, 'WEB OUTPUT')}
44
+ ${t(C.grey, '# .ss files with page/add commands auto-generate .html:')}
45
+ ${t(C.grey, '$ structscript page.ss → writes page.html')}
46
+ ${t(C.grey, '$ structscript page.ss --output=out.html')}
40
47
  ${t(C.lime, 'structscript')} ${t(C.teal, 'help')} Show this help
41
48
 
42
49
  ${t(C.bold, 'OPTIONS')}
@@ -74,7 +81,60 @@ if (cmd === 'version' || cmd === '--version' || cmd === '-v') {
74
81
  process.exit(0);
75
82
  }
76
83
 
77
- if (cmd === 'repl') {
84
+ if (cmd === 'editor') {
85
+ const { spawnSync } = require('child_process');
86
+ const mainJs = path.join(__dirname, '../lib/main.js');
87
+ const fileArg = params[1] ? [path.resolve(params[1])] : [];
88
+
89
+ // Find electron — it lives in a local node_modules next to the structscript package
90
+ function findElectron() {
91
+ // 1. Already installed next to this package
92
+ const localPkg = path.join(__dirname, '../node_modules/.bin/electron');
93
+ if (fs.existsSync(localPkg)) return localPkg;
94
+ // On Windows the bin has .cmd extension
95
+ if (fs.existsSync(localPkg + '.cmd')) return localPkg + '.cmd';
96
+ // 2. Try requiring it (works if installed as a dep somewhere up the tree)
97
+ try { return require('electron'); } catch (_) {}
98
+ return null;
99
+ }
100
+
101
+ let electronPath = findElectron();
102
+
103
+ if (!electronPath) {
104
+ // Auto-install electron into the package's own node_modules
105
+ console.log(t(C.teal, ' Installing Electron for the first time (this takes ~30s)…'));
106
+ const pkgDir = path.join(__dirname, '..');
107
+ const install = spawnSync(
108
+ process.execPath, // node
109
+ [require.resolve('npm/bin/npm-cli'), 'install', '--prefix', pkgDir, 'electron', '--save-optional'],
110
+ { stdio: 'inherit', cwd: pkgDir }
111
+ );
112
+ if (install.status !== 0) {
113
+ // npm-cli path failed, try plain npm command
114
+ const install2 = spawnSync(
115
+ process.platform === 'win32' ? 'npm.cmd' : 'npm',
116
+ ['install', '--prefix', pkgDir, 'electron'],
117
+ { stdio: 'inherit', cwd: pkgDir, shell: true }
118
+ );
119
+ if (install2.status !== 0) {
120
+ console.error(t(C.red, 'Failed to install Electron. Please run:'));
121
+ console.error(t(C.grey, ' npm install electron'));
122
+ console.error(t(C.grey, ' (inside: ' + pkgDir + ')'));
123
+ process.exit(1);
124
+ }
125
+ }
126
+ electronPath = findElectron();
127
+ if (!electronPath) {
128
+ console.error(t(C.red, 'Could not locate Electron after install. Please run:'));
129
+ console.error(t(C.grey, ' npm install electron (inside: ' + path.join(__dirname, '..') + ')'));
130
+ process.exit(1);
131
+ }
132
+ console.log(t(C.lime, ' Electron installed!'));
133
+ }
134
+
135
+ const result = spawnSync(electronPath, [mainJs, ...fileArg], { stdio: 'inherit' });
136
+ process.exit(result.status || 0);
137
+ } else if (cmd === 'repl') {
78
138
  startREPL();
79
139
  } else if (cmd === 'run') {
80
140
  const file = params[1];
@@ -113,6 +173,11 @@ function runFile(filePath) {
113
173
  output: msg => console.log(msg),
114
174
  warn: msg => console.warn(t(C.yellow, '⚠ ' + msg)),
115
175
  });
176
+ interp._sourceFile = resolved;
177
+
178
+ // --output flag: structscript page.ss --output page.html
179
+ const outFlag = args.find(a => a.startsWith('--output='));
180
+ if (outFlag) interp._htmlOutputFile = outFlag.split('=')[1];
116
181
 
117
182
  try {
118
183
  interp.run(source);
@@ -257,4 +322,4 @@ function executeREPL(interp, code) {
257
322
  console.error(t(C.grey, ` → ${e.snippet.trim()}`));
258
323
  }
259
324
  }
260
- }
325
+ }