rhythmx 0.0.13
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/dist/bin.js +112 -0
- package/package.json +39 -0
package/dist/bin.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// src/bin.ts
|
|
5
|
+
import { toCliHandler } from "@rhythmjs/cli/run";
|
|
6
|
+
|
|
7
|
+
// src/app.ts
|
|
8
|
+
import { Rhythm } from "@rhythmjs/rhythm";
|
|
9
|
+
import { RhythmCli } from "@rhythmjs/cli";
|
|
10
|
+
import { createPrompt } from "@rhythmjs/cli/run";
|
|
11
|
+
|
|
12
|
+
// src/scaffold.ts
|
|
13
|
+
import { existsSync, readdirSync } from "fs";
|
|
14
|
+
import { basename, resolve } from "path";
|
|
15
|
+
import { rm } from "fs/promises";
|
|
16
|
+
var DEFAULT_TEMPLATE = "https://github.com/rhythmjs/template";
|
|
17
|
+
var PACKAGE_NAME = /^[a-z0-9][a-z0-9._~-]*$/;
|
|
18
|
+
function validateName(name) {
|
|
19
|
+
const packageName = basename(resolve(name));
|
|
20
|
+
if (!PACKAGE_NAME.test(packageName)) {
|
|
21
|
+
return `"${packageName}" is not a valid project name (lowercase letters, numbers, ".", "_", "~" and "-" only).`;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
async function run(cmd, cwd, inherit = false) {
|
|
26
|
+
const proc = Bun.spawn(cmd, {
|
|
27
|
+
cwd,
|
|
28
|
+
stdin: "ignore",
|
|
29
|
+
stdout: inherit ? "inherit" : "ignore",
|
|
30
|
+
stderr: inherit ? "inherit" : "pipe"
|
|
31
|
+
});
|
|
32
|
+
const code = await proc.exited;
|
|
33
|
+
if (code !== 0 && !inherit && proc.stderr) {
|
|
34
|
+
const message = (await new Response(proc.stderr).text()).trim();
|
|
35
|
+
if (message)
|
|
36
|
+
console.error(message);
|
|
37
|
+
}
|
|
38
|
+
return code;
|
|
39
|
+
}
|
|
40
|
+
async function scaffold(options) {
|
|
41
|
+
const invalid = validateName(options.name);
|
|
42
|
+
if (invalid)
|
|
43
|
+
throw new Error(invalid);
|
|
44
|
+
const dir = resolve(options.name);
|
|
45
|
+
const packageName = basename(dir);
|
|
46
|
+
if (existsSync(dir) && readdirSync(dir).length > 0) {
|
|
47
|
+
throw new Error(`Directory "${options.name}" already exists and is not empty.`);
|
|
48
|
+
}
|
|
49
|
+
const template = options.template ?? DEFAULT_TEMPLATE;
|
|
50
|
+
if (await run(["git", "clone", "--depth", "1", template, dir]) !== 0) {
|
|
51
|
+
throw new Error(`Could not clone template ${template}. Is git installed and the template reachable?`);
|
|
52
|
+
}
|
|
53
|
+
await rm(resolve(dir, ".git"), { recursive: true, force: true });
|
|
54
|
+
await run(["git", "init"], dir);
|
|
55
|
+
const pkgPath = resolve(dir, "package.json");
|
|
56
|
+
if (existsSync(pkgPath)) {
|
|
57
|
+
const pkg = await Bun.file(pkgPath).json();
|
|
58
|
+
pkg.name = packageName;
|
|
59
|
+
await Bun.write(pkgPath, JSON.stringify(pkg, null, 2) + `
|
|
60
|
+
`);
|
|
61
|
+
}
|
|
62
|
+
let installed = false;
|
|
63
|
+
if (options.install !== false && existsSync(pkgPath)) {
|
|
64
|
+
installed = await run(["bun", "install"], dir, true) === 0;
|
|
65
|
+
}
|
|
66
|
+
return { dir, packageName, installed };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/app.ts
|
|
70
|
+
var HELP = `Usage: rhythm <command>
|
|
71
|
+
|
|
72
|
+
Commands:
|
|
73
|
+
new [name] Create a new Rhythm project from the template
|
|
74
|
+
|
|
75
|
+
Options for new:
|
|
76
|
+
--template <url> Clone a different template (git URL or path)
|
|
77
|
+
--no-install Skip \`bun install\``;
|
|
78
|
+
var cli = new RhythmCli;
|
|
79
|
+
var create = async (ctx) => {
|
|
80
|
+
let name = ctx.args["name"];
|
|
81
|
+
if (!name) {
|
|
82
|
+
const { prompt, close } = createPrompt();
|
|
83
|
+
name = await prompt.text("Project name?", { default: "my-app" });
|
|
84
|
+
close();
|
|
85
|
+
}
|
|
86
|
+
const template = typeof ctx.flags.template === "string" ? ctx.flags.template : undefined;
|
|
87
|
+
try {
|
|
88
|
+
const result = await scaffold({ name, template, install: !ctx.flags["no-install"] });
|
|
89
|
+
ctx.response.print(`
|
|
90
|
+
Created ${result.packageName} in ${result.dir}
|
|
91
|
+
|
|
92
|
+
Next steps:
|
|
93
|
+
cd ${name}`);
|
|
94
|
+
if (!result.installed)
|
|
95
|
+
ctx.response.print(" bun install");
|
|
96
|
+
ctx.response.print(" bun dev");
|
|
97
|
+
} catch (error) {
|
|
98
|
+
ctx.response.exit(1).printError(error instanceof Error ? error.message : String(error));
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
cli.command("new :name?", create);
|
|
102
|
+
var app = new Rhythm({ name: "rhythm" }).use(cli.middleware()).use((ctx) => {
|
|
103
|
+
const unknown = ctx.argv.length > 0 && !ctx.flags.help && !ctx.flags.h;
|
|
104
|
+
if (unknown)
|
|
105
|
+
ctx.response.exit(1).printError(`Unknown command: ${ctx.argv.join(" ")}
|
|
106
|
+
`);
|
|
107
|
+
ctx.response.print(HELP);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// src/bin.ts
|
|
111
|
+
process.exitCode = await toCliHandler(app)(process.argv.slice(2));
|
|
112
|
+
await app.teardown();
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rhythmx",
|
|
3
|
+
"version": "0.0.13",
|
|
4
|
+
"description": "The Rhythm CLI: scaffold and manage Rhythm projects from the command line, running on Bun.",
|
|
5
|
+
"homepage": "https://rhythm.js.org",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/rhythmjs/rhythm.git",
|
|
10
|
+
"directory": "packages/rhythmx"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"bin": {
|
|
17
|
+
"rhythm": "./dist/bin.js"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@rhythmjs/cli": "0.0.13",
|
|
24
|
+
"@rhythmjs/rhythm": "0.0.13"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/bun": "^1.4.2",
|
|
28
|
+
"@types/node": "^26.6.3",
|
|
29
|
+
"typescript": "^7.0.2"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"bun": ">=1.2.0"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "bun build src/bin.ts --outdir dist --root src --format esm --target bun --packages external",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"test": "bun test"
|
|
38
|
+
}
|
|
39
|
+
}
|