structscript 1.2.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.
- package/bin/structscript.js +67 -2
- package/lib/editor.html +3247 -0
- package/lib/interpreter.js +20 -1
- package/lib/main.js +261 -0
- package/lib/preload.js +21 -0
- package/package.json +7 -5
package/bin/structscript.js
CHANGED
|
@@ -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 === '
|
|
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
|
+
}
|