@njinlabs/njin 0.3.0 → 0.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/README.md +7 -1
- package/package.json +1 -1
- package/src/cli/create.ts +82 -0
- package/src/cli/index.ts +8 -4
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# njin
|
|
2
2
|
|
|
3
|
+
[](https://github.com/njinlabs/njin/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/njinlabs/njin/actions/workflows/codeql.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@njinlabs/njin)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
3
8
|
A modern framework for building company profiles, landing pages, and content-driven websites. Define your data model once — get a full REST API, admin panel schema, and server-rendered website out of the box.
|
|
4
9
|
|
|
5
10
|
## Stack
|
|
@@ -13,7 +18,7 @@ A modern framework for building company profiles, landing pages, and content-dri
|
|
|
13
18
|
## Quick start
|
|
14
19
|
|
|
15
20
|
```bash
|
|
16
|
-
|
|
21
|
+
bunx @njinlabs/njin create my-web
|
|
17
22
|
cd my-web
|
|
18
23
|
bunx njin dev
|
|
19
24
|
```
|
|
@@ -389,6 +394,7 @@ adapters: {
|
|
|
389
394
|
## Commands
|
|
390
395
|
|
|
391
396
|
```bash
|
|
397
|
+
bunx @njinlabs/njin create my-web # Scaffold a new project
|
|
392
398
|
bunx njin dev # Start dev server (Elysia + Vite HMR)
|
|
393
399
|
bunx njin build # Build for production -> ./out (public/, _admin/, views/, compiled server)
|
|
394
400
|
bunx njin start # Run from source in production mode (no compile)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@njinlabs/njin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A modern framework for building company profiles, landing pages, and content-driven websites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": ["bun", "elysia", "surrealdb", "edgejs", "cms", "framework"],
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
const c = { reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m", cyan: "\x1b[36m", green: "\x1b[32m" };
|
|
5
|
+
|
|
6
|
+
const targetArg = process.argv[3] ?? ".";
|
|
7
|
+
const targetDir = resolve(process.cwd(), targetArg);
|
|
8
|
+
const projectName = targetArg === "." ? "njin-app" : targetArg.split(/[\\/]/).filter(Boolean).pop()!;
|
|
9
|
+
|
|
10
|
+
if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {
|
|
11
|
+
console.error(`✖ Directory "${targetArg}" already exists and is not empty.`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// This CLI's own package.json — read at runtime (not a static JSON import) so it
|
|
16
|
+
// resolves correctly whether njin is a project-local dependency or fetched fresh
|
|
17
|
+
// by `bunx`. Doubles as the source of truth for which tagged template to fetch,
|
|
18
|
+
// and for the version pin written into the scaffolded project below.
|
|
19
|
+
const pkg = await Bun.file(join(import.meta.dir, "../../package.json")).json();
|
|
20
|
+
const tag = `v${pkg.version}`;
|
|
21
|
+
const tarballUrl = `https://codeload.github.com/njinlabs/njin/tar.gz/refs/tags/${tag}`;
|
|
22
|
+
|
|
23
|
+
console.log(`\nFetching template for njin ${tag}...\n`);
|
|
24
|
+
|
|
25
|
+
const res = await fetch(tarballUrl);
|
|
26
|
+
if (!res.ok || !res.body) {
|
|
27
|
+
console.error(
|
|
28
|
+
`✖ Could not download the project template for njin ${tag} (HTTP ${res.status}).\n` +
|
|
29
|
+
` Check your internet connection, or that tag "${tag}" exists at github.com/njinlabs/njin.`,
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
mkdirSync(targetDir, { recursive: true });
|
|
35
|
+
|
|
36
|
+
// `--strip-components=2` drops the `njin-<version>/template/` prefix baked into
|
|
37
|
+
// GitHub's tag-tarball layout, so template/ contents land directly in targetDir.
|
|
38
|
+
const tar = Bun.spawn(["tar", "-xz", "--strip-components=2", "-C", targetDir, `njin-${pkg.version}/template`], {
|
|
39
|
+
stdin: res.body,
|
|
40
|
+
stdout: "inherit",
|
|
41
|
+
stderr: "inherit",
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const tarExitCode = await tar.exited;
|
|
45
|
+
|
|
46
|
+
if (tarExitCode !== 0) {
|
|
47
|
+
console.error(
|
|
48
|
+
`✖ Failed to extract the template (tar exited with code ${tarExitCode}).\n` +
|
|
49
|
+
` Make sure "tar" is installed and available on your PATH.`,
|
|
50
|
+
);
|
|
51
|
+
process.exit(tarExitCode);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const pkgPath = join(targetDir, "package.json");
|
|
55
|
+
const scaffoldedPkg = await Bun.file(pkgPath).json();
|
|
56
|
+
scaffoldedPkg.name = projectName;
|
|
57
|
+
scaffoldedPkg.dependencies = { "@njinlabs/njin": `^${pkg.version}`, ...scaffoldedPkg.dependencies };
|
|
58
|
+
await Bun.write(pkgPath, JSON.stringify(scaffoldedPkg, null, 2) + "\n");
|
|
59
|
+
|
|
60
|
+
console.log("Installing dependencies...\n");
|
|
61
|
+
|
|
62
|
+
const install = Bun.spawn(["bun", "install"], {
|
|
63
|
+
cwd: targetDir,
|
|
64
|
+
stdout: "inherit",
|
|
65
|
+
stderr: "inherit",
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const installExitCode = await install.exited;
|
|
69
|
+
|
|
70
|
+
if (installExitCode !== 0) {
|
|
71
|
+
console.error(`\n✖ "bun install" failed (exit code ${installExitCode}).`);
|
|
72
|
+
console.error(` The project was scaffolded at ${targetDir}, but dependencies are not installed.`);
|
|
73
|
+
console.error(` Run "cd ${targetArg} && bun install" manually to retry.\n`);
|
|
74
|
+
process.exit(installExitCode);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`
|
|
78
|
+
${c.bold}${c.cyan}njin create${c.reset} ${c.dim}done${c.reset}
|
|
79
|
+
|
|
80
|
+
${c.green}➜${c.reset} cd ${targetArg === "." ? "." : targetArg}
|
|
81
|
+
${c.green}➜${c.reset} bunx njin dev
|
|
82
|
+
`);
|
package/src/cli/index.ts
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
const [command] = process.argv.slice(2);
|
|
3
3
|
|
|
4
4
|
switch (command) {
|
|
5
|
+
case "create":
|
|
6
|
+
await import("./create");
|
|
7
|
+
break;
|
|
5
8
|
case "dev":
|
|
6
9
|
await import("./dev");
|
|
7
10
|
break;
|
|
@@ -12,10 +15,11 @@ switch (command) {
|
|
|
12
15
|
await import("./build");
|
|
13
16
|
break;
|
|
14
17
|
default:
|
|
15
|
-
console.log(`Usage: njin <dev|build|start>
|
|
18
|
+
console.log(`Usage: njin <create|dev|build|start>
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
create <dir> Scaffold a new project (defaults to current directory)
|
|
21
|
+
dev Run the dev server (Vite HMR + live reload)
|
|
22
|
+
build Build for production -> ./out (public/, _admin/, views/, server)
|
|
23
|
+
start Run from source in production mode (no compile)`);
|
|
20
24
|
process.exit(command ? 1 : 0);
|
|
21
25
|
}
|