janela 0.14.2 → 0.14.3
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/README.md +6 -1
- package/bin/janela.mjs +55 -11
- package/bin/lib.mjs +27 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,10 +43,15 @@ Or start from a frontend framework:
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
janela init my-app --template vue # or react | svelte | solid | vanilla
|
|
46
|
-
cd my-app
|
|
46
|
+
cd my-app # deps are already installed
|
|
47
47
|
janela dev # Vite dev server + HMR, in a native window
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
`init` installs the template's dependencies with whichever package manager
|
|
51
|
+
ran it — `pnpm janela init` uses pnpm — so `janela dev` works straight
|
|
52
|
+
afterwards. Pass `--no-install` to skip that, and if the install fails the
|
|
53
|
+
project is still written; the message names the one command to retry.
|
|
54
|
+
|
|
50
55
|
A `--template` a globally installed CLI has never heard of is now an error
|
|
51
56
|
rather than a silent fallback, and `janela --version` says which one you are
|
|
52
57
|
running — worth checking first if a scaffolded project comes out looking
|
package/bin/janela.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// janela — the CLI (the tauri-cli analogue).
|
|
3
3
|
//
|
|
4
|
-
// janela init <name> scaffold a new project
|
|
4
|
+
// janela init <name> scaffold a new project (and install its dependencies)
|
|
5
5
|
// janela build compile the project to a native binary (+ .app on macOS)
|
|
6
6
|
// janela dev build, then run the binary with logs in the terminal
|
|
7
7
|
// janela --version which janela this is
|
|
@@ -21,8 +21,8 @@ import { dirname, join, relative, resolve, sep } from "node:path";
|
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
22
|
import {
|
|
23
23
|
ANDROID_ABI, ANDROID_TARGET_SDK, androidConf, ffiManifest, iosConf,
|
|
24
|
-
libraryProfile, mimeFor, NAME_RE,
|
|
25
|
-
rewriteHostSpecifier, suggestName,
|
|
24
|
+
installCommand, libraryProfile, mimeFor, NAME_RE, packageManager as pmFor,
|
|
25
|
+
patchPeSubsystem, PeError, rewriteHostSpecifier, suggestName,
|
|
26
26
|
} from "./lib.mjs";
|
|
27
27
|
|
|
28
28
|
const KIT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
@@ -107,8 +107,9 @@ function viteCommand(root) {
|
|
|
107
107
|
if (existsSync(shim)) return { argv: [shim], shell: process.platform === "win32" };
|
|
108
108
|
|
|
109
109
|
fail(
|
|
110
|
-
"this project has a vite config but no local vite —
|
|
111
|
-
|
|
110
|
+
"this project has a vite config but no local vite — its dependencies are not " +
|
|
111
|
+
`installed yet:\n ${installCommand(pmFor(process.env)).join(" ")}\n` +
|
|
112
|
+
" (janela init installs them for you unless you pass --no-install)",
|
|
112
113
|
);
|
|
113
114
|
}
|
|
114
115
|
|
|
@@ -1160,7 +1161,29 @@ function copyTemplate(from, to, name) {
|
|
|
1160
1161
|
|
|
1161
1162
|
// Best-effort repair of a rejected name, so the error can suggest something
|
|
1162
1163
|
// that would have worked instead of only stating the rule.
|
|
1163
|
-
|
|
1164
|
+
/**
|
|
1165
|
+
* Install a scaffolded project's dependencies.
|
|
1166
|
+
*
|
|
1167
|
+
* Returns true on success. A failure is NOT fatal: the project is already
|
|
1168
|
+
* written, and the useful thing to do is name the one command to retry rather
|
|
1169
|
+
* than exit non-zero on a tree that is fine. Offline, an unreachable registry
|
|
1170
|
+
* and missing auth all land here.
|
|
1171
|
+
*
|
|
1172
|
+
* Windows needs a shell: npm/pnpm/yarn are .cmd shims, and Node has refused to
|
|
1173
|
+
* spawn those directly since the CVE-2024-27980 fix.
|
|
1174
|
+
*/
|
|
1175
|
+
function installDeps(dir, pm) {
|
|
1176
|
+
const cmd = installCommand(pm);
|
|
1177
|
+
console.log(`janela: installing dependencies with ${pm}…`);
|
|
1178
|
+
const r = spawnSync(cmd[0], cmd.slice(1), {
|
|
1179
|
+
stdio: "inherit",
|
|
1180
|
+
cwd: dir,
|
|
1181
|
+
shell: process.platform === "win32",
|
|
1182
|
+
});
|
|
1183
|
+
return r.status === 0;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
function init(name, template, { install = true } = {}) {
|
|
1164
1187
|
if (!name) {
|
|
1165
1188
|
fail(
|
|
1166
1189
|
"no project name given.\n" +
|
|
@@ -1216,8 +1239,27 @@ function init(name, template) {
|
|
|
1216
1239
|
writeFileSync(join(dir, ".gitignore"), ".janela/\nnode_modules/\ndist/\n");
|
|
1217
1240
|
writeFileSync(join(dir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
1218
1241
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1242
|
+
// The no-framework template has no dependencies to install: it needs no
|
|
1243
|
+
// frontend toolchain, and `janela dev` works on it straight out of init.
|
|
1244
|
+
const hasDeps = template !== "vanilla";
|
|
1245
|
+
if (!hasDeps || !install) {
|
|
1246
|
+
// Only a skipped install on a template that HAS dependencies leaves the
|
|
1247
|
+
// caller something to run.
|
|
1248
|
+
const manual = hasDeps ? `${installCommand(pmFor(process.env)).join(" ")} && ` : "";
|
|
1249
|
+
console.log(`janela: created ${name}/ (${template}) — next: cd ${name} && ${manual}janela dev`);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
const pm = pmFor(process.env);
|
|
1254
|
+
if (installDeps(dir, pm)) {
|
|
1255
|
+
console.log(`janela: created ${name}/ (${template}) — next: cd ${name} && janela dev`);
|
|
1256
|
+
} else {
|
|
1257
|
+
console.log(
|
|
1258
|
+
`janela: created ${name}/ (${template}), but installing its dependencies failed.\n` +
|
|
1259
|
+
` The project is written and fine — retry the install and you are set:\n` +
|
|
1260
|
+
` cd ${name} && ${installCommand(pm).join(" ")} && janela dev`,
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1221
1263
|
}
|
|
1222
1264
|
|
|
1223
1265
|
// ---- dev --------------------------------------------------------------------
|
|
@@ -1349,9 +1391,11 @@ function assertPositionals(max) {
|
|
|
1349
1391
|
|
|
1350
1392
|
switch (cmd) {
|
|
1351
1393
|
case "init":
|
|
1352
|
-
assertKnownFlags(["template"]);
|
|
1394
|
+
assertKnownFlags(["template", "no-install"]);
|
|
1353
1395
|
assertPositionals(1);
|
|
1354
|
-
init(positionals()[0], flag("template", "vanilla")
|
|
1396
|
+
init(positionals()[0], flag("template", "vanilla"), {
|
|
1397
|
+
install: !argv.includes("--no-install"),
|
|
1398
|
+
});
|
|
1355
1399
|
break;
|
|
1356
1400
|
case "build":
|
|
1357
1401
|
assertKnownFlags(["target"]);
|
|
@@ -1371,7 +1415,7 @@ switch (cmd) {
|
|
|
1371
1415
|
default:
|
|
1372
1416
|
console.log(
|
|
1373
1417
|
`janela ${VERSION}\n\n` +
|
|
1374
|
-
"usage: janela init <name> [--template vanilla|vue|react|svelte|solid]\n" +
|
|
1418
|
+
"usage: janela init <name> [--template vanilla|vue|react|svelte|solid] [--no-install]\n" +
|
|
1375
1419
|
" janela build [--target desktop|ios|android]\n" +
|
|
1376
1420
|
" janela dev [--target desktop|ios|android]\n" +
|
|
1377
1421
|
" janela --version",
|
package/bin/lib.mjs
CHANGED
|
@@ -345,3 +345,30 @@ export function patchPeSubsystem(input) {
|
|
|
345
345
|
buf.writeUInt16LE(IMAGE_SUBSYSTEM_WINDOWS_GUI, subOff);
|
|
346
346
|
return { patched: true, buf };
|
|
347
347
|
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Which package manager to install a scaffolded project with.
|
|
351
|
+
*
|
|
352
|
+
* `npm_config_user_agent` is set by whichever manager ran janela, so
|
|
353
|
+
* `pnpm janela init` installs with pnpm. Run as a plain global binary it is
|
|
354
|
+
* unset, and npm is the only manager guaranteed to exist alongside node.
|
|
355
|
+
*
|
|
356
|
+
* Takes the environment rather than reading process.env, so it is testable.
|
|
357
|
+
*/
|
|
358
|
+
export function packageManager(env = {}) {
|
|
359
|
+
const ua = env.npm_config_user_agent ?? "";
|
|
360
|
+
for (const pm of ["pnpm", "yarn", "bun"]) if (ua.startsWith(`${pm}/`)) return pm;
|
|
361
|
+
return "npm";
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* The install invocation for a manager.
|
|
366
|
+
*
|
|
367
|
+
* yarn's is the bare command. npm gets --no-fund --no-audit: neither is useful
|
|
368
|
+
* on a freshly scaffolded tree, and the audit is the slowest part of it.
|
|
369
|
+
*/
|
|
370
|
+
export function installCommand(pm) {
|
|
371
|
+
if (pm === "yarn") return ["yarn"];
|
|
372
|
+
if (pm === "npm") return ["npm", "install", "--no-fund", "--no-audit"];
|
|
373
|
+
return [pm, "install"];
|
|
374
|
+
}
|