feega 0.1.3 → 0.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.
- package/bin/feega.mjs +16 -4
- package/launcher.mjs +29 -2
- package/package.json +1 -1
package/bin/feega.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
-
import { createWriteStream, mkdirSync, realpathSync, rmSync } from 'node:fs';
|
|
3
|
+
import { createWriteStream, mkdirSync, readFileSync, realpathSync, rmSync } from 'node:fs';
|
|
4
4
|
import { homedir, tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { Readable } from 'node:stream';
|
|
7
7
|
import { pipeline } from 'node:stream/promises';
|
|
8
8
|
|
|
9
|
-
import { appDir, bundleSource, cachedVersions, isCached, latestAppVersion, markCached, parseArgs, pickVersion } from '../launcher.mjs';
|
|
9
|
+
import { USAGE, appDir, bundleSource, boundUrl, cachedVersions, freePort, isCached, latestAppVersion, markCached, parseArgs, pickVersion } from '../launcher.mjs';
|
|
10
10
|
|
|
11
11
|
const MIN_NODE_MAJOR = 22;
|
|
12
12
|
const WEBSTORAGE_NODE_MAJOR = 25;
|
|
@@ -88,14 +88,26 @@ async function main() {
|
|
|
88
88
|
throw new Error(`Node ${MIN_NODE_MAJOR}+ is required (found ${process.versions.node})`);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
const
|
|
91
|
+
const args = parseArgs(process.argv.slice(2), process.cwd());
|
|
92
|
+
if (args.command === 'help') {
|
|
93
|
+
console.log(USAGE);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (args.command === 'version') {
|
|
98
|
+
console.log(JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const { file, browser } = args;
|
|
103
|
+
const port = await freePort(args.port);
|
|
92
104
|
const { version, action } = await chooseVersion(homedir());
|
|
93
105
|
const dir = appDir(homedir(), version);
|
|
94
106
|
if (action === 'download') {
|
|
95
107
|
await install(dir, version);
|
|
96
108
|
}
|
|
97
109
|
|
|
98
|
-
const url =
|
|
110
|
+
const url = boundUrl(port);
|
|
99
111
|
console.log(`feega: saving to ${file}`);
|
|
100
112
|
console.log(`feega: open ${url}`);
|
|
101
113
|
|
package/launcher.mjs
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { createServer } from 'node:net';
|
|
2
3
|
import { join, resolve } from 'node:path';
|
|
3
4
|
|
|
4
5
|
const DEFAULT_FILE = 'canvas.feega';
|
|
5
|
-
const DEFAULT_PORT =
|
|
6
|
+
const DEFAULT_PORT = 0;
|
|
7
|
+
export const LOOPBACK = '127.0.0.1';
|
|
8
|
+
export const USAGE = `usage: feega [file.feega] [--port <n>] [--no-open] [--help] [--version]`;
|
|
6
9
|
const CACHED_MARKER = '.complete';
|
|
7
10
|
const APP_TAG = 'app-v';
|
|
8
11
|
const RELEASES = 'https://github.com/andreabuttarelli/feega/releases/download';
|
|
@@ -25,6 +28,14 @@ export function parseArgs(argv, cwd) {
|
|
|
25
28
|
|
|
26
29
|
while (rest.length) {
|
|
27
30
|
const arg = rest.shift();
|
|
31
|
+
if (arg === '--help' || arg === '-h') {
|
|
32
|
+
return { command: 'help' };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (arg === '--version') {
|
|
36
|
+
return { command: 'version' };
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
if (arg === '--no-open') {
|
|
29
40
|
browser = 'skip';
|
|
30
41
|
continue;
|
|
@@ -40,10 +51,14 @@ export function parseArgs(argv, cwd) {
|
|
|
40
51
|
continue;
|
|
41
52
|
}
|
|
42
53
|
|
|
54
|
+
if (arg.startsWith('-')) {
|
|
55
|
+
throw new Error(`unknown option: ${arg}\n${USAGE}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
43
58
|
files.push(arg);
|
|
44
59
|
}
|
|
45
60
|
|
|
46
|
-
return { file: resolve(cwd, files[0] ?? DEFAULT_FILE), port, browser };
|
|
61
|
+
return { command: 'run', file: resolve(cwd, files[0] ?? DEFAULT_FILE), port, browser };
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
export const appDir = (home, version) => join(home, '.feega', 'app', version);
|
|
@@ -94,3 +109,15 @@ export function pickVersion(latest, cached) {
|
|
|
94
109
|
|
|
95
110
|
return { version: cached[0], action: 'cache' };
|
|
96
111
|
}
|
|
112
|
+
|
|
113
|
+
export const boundUrl = (port) => `http://${LOOPBACK}:${port}`;
|
|
114
|
+
|
|
115
|
+
export const freePort = (port) =>
|
|
116
|
+
new Promise((done, fail) => {
|
|
117
|
+
const probe = createServer();
|
|
118
|
+
probe.once('error', fail);
|
|
119
|
+
probe.listen(port, LOOPBACK, () => {
|
|
120
|
+
const { port: bound } = probe.address();
|
|
121
|
+
probe.close(() => done(bound));
|
|
122
|
+
});
|
|
123
|
+
});
|