niral 0.1.1 → 0.1.2
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/create-niral.js +26 -15
- package/bin/niral.js +11 -2
- package/index.js +43 -23
- package/package.json +1 -1
package/bin/create-niral.js
CHANGED
|
@@ -2,20 +2,31 @@
|
|
|
2
2
|
// npx create-niral my-app — the beginner's one command.
|
|
3
3
|
import { ensureFramework, installLauncher, runNiral } from "../index.js";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const usage = "usage: npx create-niral <app-name|.> [--template minimal|blog|dashboard]";
|
|
6
|
+
|
|
7
|
+
async function main(argv = process.argv.slice(2)) {
|
|
8
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
9
|
+
console.log(usage);
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
const name = argv[0];
|
|
13
|
+
if (!name || (name.startsWith("-") && name !== ".")) throw new Error(usage);
|
|
10
14
|
|
|
11
|
-
await ensureFramework();
|
|
12
|
-
const code = runNiral(["create", name]);
|
|
13
|
-
if (code !== 0)
|
|
15
|
+
await ensureFramework();
|
|
16
|
+
const code = runNiral(["create", name, ...argv.slice(1)]);
|
|
17
|
+
if (code !== 0) return code;
|
|
18
|
+
|
|
19
|
+
const { profile, added } = installLauncher();
|
|
20
|
+
console.log("");
|
|
21
|
+
if (added) console.log(`✓ \`niral\` command installed — PATH updated in ${profile} (open a new terminal)`);
|
|
22
|
+
const cd = name === "." ? "" : ` cd ${name}\n`;
|
|
23
|
+
console.log(`Next:\n${cd} niral dev # or: npx niral dev\n`);
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
14
26
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
console.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
`);
|
|
27
|
+
main().then((code) => {
|
|
28
|
+
process.exitCode = code;
|
|
29
|
+
}).catch((error) => {
|
|
30
|
+
console.error(`create-niral: ${error?.message || error}`);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
});
|
package/bin/niral.js
CHANGED
|
@@ -3,5 +3,14 @@
|
|
|
3
3
|
// Available globally after `npm i -g create-niral`, or per-call via `npx niral dev`.
|
|
4
4
|
import { ensureFramework, runNiral } from "../index.js";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
async function main() {
|
|
7
|
+
await ensureFramework();
|
|
8
|
+
return runNiral(process.argv.slice(2));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
main().then((code) => {
|
|
12
|
+
process.exitCode = code;
|
|
13
|
+
}).catch((error) => {
|
|
14
|
+
console.error(`niral: ${error?.message || error}`);
|
|
15
|
+
process.exitCode = 1;
|
|
16
|
+
});
|
package/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { existsSync, mkdirSync, rmSync, writeFileSync, chmodSync, appendFileSync, readFileSync } from "node:fs";
|
|
10
|
-
import { spawnSync
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { homedir } from "node:os";
|
|
13
13
|
import { get } from "node:https";
|
|
@@ -33,12 +33,23 @@ function download(url, dest) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function hasGit() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
36
|
+
const result = spawnSync("git", ["--version"], { stdio: "ignore" });
|
|
37
|
+
return !result.error && result.status === 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function commandError(label, result) {
|
|
41
|
+
const detail = result.error?.message || result.stderr?.trim() || `exit ${result.status ?? "unknown"}`;
|
|
42
|
+
return new Error(`${label} failed: ${detail}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function installFromTarball() {
|
|
46
|
+
const tgz = join(NIRAL_HOME, "niral.tgz");
|
|
47
|
+
await download(TARBALL, tgz);
|
|
48
|
+
rmSync(FRAMEWORK, { recursive: true, force: true });
|
|
49
|
+
mkdirSync(FRAMEWORK, { recursive: true });
|
|
50
|
+
const extracted = spawnSync("tar", ["-xzf", tgz, "-C", FRAMEWORK, "--strip-components=1"], { encoding: "utf8" });
|
|
51
|
+
rmSync(tgz, { force: true });
|
|
52
|
+
if (extracted.error || extracted.status !== 0) throw commandError("framework extraction", extracted);
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
/** Download the framework to ~/.niral/framework (git if available, tarball otherwise). */
|
|
@@ -46,21 +57,22 @@ export async function ensureFramework({ update = false } = {}) {
|
|
|
46
57
|
if (existsSync(join(FRAMEWORK, "bin", "niral.js")) && !update) return FRAMEWORK;
|
|
47
58
|
console.log("niral · downloading the framework (one time, ~1 MB — it has zero dependencies)…");
|
|
48
59
|
mkdirSync(NIRAL_HOME, { recursive: true });
|
|
60
|
+
let installed = false;
|
|
49
61
|
if (hasGit()) {
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
const gitResult = existsSync(join(FRAMEWORK, ".git"))
|
|
63
|
+
? spawnSync("git", ["pull", "--ff-only", "-q"], { cwd: FRAMEWORK, encoding: "utf8" })
|
|
64
|
+
: (() => {
|
|
65
|
+
rmSync(FRAMEWORK, { recursive: true, force: true });
|
|
66
|
+
return spawnSync("git", ["clone", "-q", "--depth", "1", REPO, FRAMEWORK], { encoding: "utf8" });
|
|
67
|
+
})();
|
|
68
|
+
if (!gitResult.error && gitResult.status === 0) {
|
|
69
|
+
installed = true;
|
|
52
70
|
} else {
|
|
53
|
-
|
|
54
|
-
|
|
71
|
+
const reason = gitResult.error?.message || gitResult.stderr?.trim() || `exit ${gitResult.status ?? "unknown"}`;
|
|
72
|
+
console.warn(`niral · Git download unavailable (${reason}); trying the release tarball…`);
|
|
55
73
|
}
|
|
56
|
-
} else {
|
|
57
|
-
const tgz = join(NIRAL_HOME, "niral.tgz");
|
|
58
|
-
await download(TARBALL, tgz);
|
|
59
|
-
rmSync(FRAMEWORK, { recursive: true, force: true });
|
|
60
|
-
mkdirSync(FRAMEWORK, { recursive: true });
|
|
61
|
-
execSync(`tar -xzf "${tgz}" -C "${FRAMEWORK}" --strip-components=1`, { stdio: "ignore" });
|
|
62
|
-
rmSync(tgz);
|
|
63
74
|
}
|
|
75
|
+
if (!installed) await installFromTarball();
|
|
64
76
|
if (!existsSync(join(FRAMEWORK, "bin", "niral.js"))) throw new Error("framework download failed — try again or clone github.com/Zyora-Dev/niral manually");
|
|
65
77
|
return FRAMEWORK;
|
|
66
78
|
}
|
|
@@ -69,9 +81,14 @@ export async function ensureFramework({ update = false } = {}) {
|
|
|
69
81
|
export function installLauncher() {
|
|
70
82
|
const binDir = join(NIRAL_HOME, "bin");
|
|
71
83
|
mkdirSync(binDir, { recursive: true });
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
const frameworkCli = join(FRAMEWORK, "bin", "niral.js");
|
|
85
|
+
const shim = join(binDir, process.platform === "win32" ? "niral.cmd" : "niral");
|
|
86
|
+
if (process.platform === "win32") {
|
|
87
|
+
writeFileSync(shim, `@echo off\r\n"${process.execPath}" "${frameworkCli}" %*\r\n`);
|
|
88
|
+
} else {
|
|
89
|
+
writeFileSync(shim, `#!/usr/bin/env sh\nexec "${process.execPath}" "${frameworkCli}" "$@"\n`);
|
|
90
|
+
chmodSync(shim, 0o755);
|
|
91
|
+
}
|
|
75
92
|
|
|
76
93
|
const profile =
|
|
77
94
|
(process.env.SHELL ?? "").endsWith("/zsh") ? join(homedir(), ".zshrc")
|
|
@@ -91,6 +108,9 @@ export function installLauncher() {
|
|
|
91
108
|
|
|
92
109
|
/** Forward a command to the framework CLI. */
|
|
93
110
|
export function runNiral(args) {
|
|
94
|
-
const r = spawnSync(
|
|
95
|
-
|
|
111
|
+
const r = spawnSync(process.execPath, [join(FRAMEWORK, "bin", "niral.js"), ...args], { stdio: "inherit" });
|
|
112
|
+
if (r.error) throw new Error(`could not start the Niral CLI: ${r.error.message}`);
|
|
113
|
+
if (r.signal) throw new Error(`Niral CLI terminated by ${r.signal}`);
|
|
114
|
+
if (r.status === null) throw new Error("Niral CLI exited without a status");
|
|
115
|
+
return r.status;
|
|
96
116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "niral",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Niral — the zero-dependency full-stack framework by ZyoraLabs. This package is a tiny launcher; the framework itself lives at github.com/Zyora-Dev/niral and has zero dependencies.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"niral": "bin/niral.js",
|