create-rezi 0.1.0-alpha.1

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 ADDED
@@ -0,0 +1,30 @@
1
+ # create-rezi
2
+
3
+ Scaffold a new Rezi terminal UI app.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npm create rezi my-app
9
+ cd my-app
10
+ npm start
11
+ ```
12
+
13
+ ## Templates
14
+
15
+ Choose a template interactively, or pass `--template`.
16
+
17
+ ```bash
18
+ npm create rezi my-app -- --template dashboard
19
+ npm create rezi my-app -- --template form-app
20
+ npm create rezi my-app -- --template file-browser
21
+ npm create rezi my-app -- --template streaming-viewer
22
+ ```
23
+
24
+ ## Options
25
+
26
+ - `--template <name>`: Choose a template.
27
+ - `--no-install`: Skip dependency installation.
28
+ - `--pm <npm|pnpm|yarn|bun>`: Choose a package manager.
29
+ - `--list-templates`: Print available templates.
30
+ - `--help`: Show help.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scaffold.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scaffold.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { mkdtemp, readFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { assert, test } from "@rezi-ui/testkit";
5
+ import { createProject, normalizeTemplateName, toValidPackageName } from "../scaffold.js";
6
+ test("normalizeTemplateName accepts friendly aliases", () => {
7
+ assert.equal(normalizeTemplateName("form app"), "form-app");
8
+ assert.equal(normalizeTemplateName("file-browser"), "file-browser");
9
+ assert.equal(normalizeTemplateName("streaming"), "streaming-viewer");
10
+ });
11
+ test("createProject scaffolds a dashboard project with substitutions", async () => {
12
+ const root = await mkdtemp(join(tmpdir(), "rezi-create-"));
13
+ const targetDir = join(root, "my-app");
14
+ const displayName = "My Rezi App";
15
+ const packageName = toValidPackageName("my-rezi-app");
16
+ await createProject({
17
+ targetDir,
18
+ templateKey: "dashboard",
19
+ packageName,
20
+ displayName,
21
+ });
22
+ const pkgRaw = await readFile(join(targetDir, "package.json"), "utf8");
23
+ const pkg = JSON.parse(pkgRaw);
24
+ assert.equal(pkg.name, packageName);
25
+ const main = await readFile(join(targetDir, "src", "main.ts"), "utf8");
26
+ assert.ok(main.includes(displayName));
27
+ assert.ok(!main.includes("__APP_NAME__"));
28
+ });
29
+ //# sourceMappingURL=scaffold.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.test.js","sourceRoot":"","sources":["../../src/__tests__/scaffold.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE1F,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC1D,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;IAC5D,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,CAAC;IACpE,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;IAChF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,aAAa,CAAC;IAClC,MAAM,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAEtD,MAAM,aAAa,CAAC;QAClB,SAAS;QACT,WAAW,EAAE,WAAW;QACxB,WAAW;QACX,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAqB,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAEpC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IACvE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import { relative, resolve } from "node:path";
4
+ import { cwd, exit, stdin, stdout } from "node:process";
5
+ import { createInterface } from "node:readline/promises";
6
+ import { fileURLToPath } from "node:url";
7
+ import { TEMPLATE_DEFINITIONS, createProject, isValidPackageName, normalizeTemplateName, resolveTargetName, toDisplayName, toValidPackageName, } from "./scaffold.js";
8
+ function parseArgs(argv) {
9
+ const options = {
10
+ install: true,
11
+ listTemplates: false,
12
+ help: false,
13
+ };
14
+ for (let i = 0; i < argv.length; i++) {
15
+ const arg = argv[i] ?? "";
16
+ if (arg === "--help" || arg === "-h") {
17
+ options.help = true;
18
+ continue;
19
+ }
20
+ if (arg === "--list-templates" || arg === "--templates") {
21
+ options.listTemplates = true;
22
+ continue;
23
+ }
24
+ if (arg === "--no-install" || arg === "--skip-install") {
25
+ options.install = false;
26
+ continue;
27
+ }
28
+ if (arg === "--template" || arg === "-t") {
29
+ const value = argv[i + 1];
30
+ if (!value)
31
+ throw new Error("Missing value for --template");
32
+ options.template = value;
33
+ i++;
34
+ continue;
35
+ }
36
+ if (arg.startsWith("--template=")) {
37
+ options.template = arg.slice("--template=".length);
38
+ continue;
39
+ }
40
+ if (arg === "--pm" || arg === "--package-manager") {
41
+ const value = argv[i + 1];
42
+ if (!value)
43
+ throw new Error("Missing value for --pm");
44
+ options.packageManager = value;
45
+ i++;
46
+ continue;
47
+ }
48
+ if (arg.startsWith("--pm=")) {
49
+ options.packageManager = arg.slice("--pm=".length);
50
+ continue;
51
+ }
52
+ if (arg.startsWith("-")) {
53
+ throw new Error(`Unknown option: ${arg}`);
54
+ }
55
+ if (!options.targetDir) {
56
+ options.targetDir = arg;
57
+ continue;
58
+ }
59
+ throw new Error(`Unexpected argument: ${arg}`);
60
+ }
61
+ return options;
62
+ }
63
+ function printHelp() {
64
+ stdout.write("create-rezi\n\n");
65
+ stdout.write("Usage:\n");
66
+ stdout.write(" npm create rezi my-app\n\n");
67
+ stdout.write("Options:\n");
68
+ stdout.write(" --template, -t <name> Choose a template\n");
69
+ stdout.write(" --no-install Skip dependency install\n");
70
+ stdout.write(" --pm <npm|pnpm|yarn|bun> Choose a package manager\n");
71
+ stdout.write(" --list-templates Show available templates\n");
72
+ stdout.write(" --help, -h Show this help\n");
73
+ }
74
+ function printTemplates() {
75
+ stdout.write("Available templates:\n");
76
+ TEMPLATE_DEFINITIONS.forEach((template, index) => {
77
+ stdout.write(` ${index + 1}. ${template.key.padEnd(16)} ${template.label} - ${template.description}\n`);
78
+ });
79
+ }
80
+ function detectPackageManager() {
81
+ // biome-ignore lint/complexity/useLiteralKeys: process.env uses an index signature in TS.
82
+ const ua = process.env["npm_config_user_agent"] ?? "";
83
+ if (ua.startsWith("pnpm/"))
84
+ return "pnpm";
85
+ if (ua.startsWith("yarn/"))
86
+ return "yarn";
87
+ if (ua.startsWith("bun/"))
88
+ return "bun";
89
+ return "npm";
90
+ }
91
+ function resolvePackageManager(value) {
92
+ if (!value)
93
+ return detectPackageManager();
94
+ const normalized = value.trim().toLowerCase();
95
+ if (normalized === "npm" ||
96
+ normalized === "pnpm" ||
97
+ normalized === "yarn" ||
98
+ normalized === "bun") {
99
+ return normalized;
100
+ }
101
+ throw new Error(`Unsupported package manager: ${value}`);
102
+ }
103
+ async function promptText(rl, prompt, fallback) {
104
+ const answer = await rl.question(`${prompt} (${fallback}): `);
105
+ return answer.trim() || fallback;
106
+ }
107
+ async function promptTemplate(rl) {
108
+ stdout.write("\nSelect a template:\n");
109
+ TEMPLATE_DEFINITIONS.forEach((template, index) => {
110
+ stdout.write(` ${index + 1}. ${template.label} - ${template.description}\n`);
111
+ });
112
+ const answer = await rl.question("Template (1-4, default 1): ");
113
+ const trimmed = answer.trim();
114
+ if (!trimmed)
115
+ return "dashboard";
116
+ const asNumber = Number(trimmed);
117
+ if (!Number.isNaN(asNumber) && asNumber >= 1 && asNumber <= TEMPLATE_DEFINITIONS.length) {
118
+ return TEMPLATE_DEFINITIONS[asNumber - 1]?.key ?? "dashboard";
119
+ }
120
+ return trimmed;
121
+ }
122
+ function runInstall(pm, targetDir) {
123
+ const res = spawnSync(pm, ["install"], {
124
+ cwd: targetDir,
125
+ stdio: "inherit",
126
+ });
127
+ if (res.status !== 0) {
128
+ throw new Error(`${pm} install failed`);
129
+ }
130
+ }
131
+ function printNextSteps(targetDir, packageManager, installRan) {
132
+ const rel = relative(cwd(), resolve(targetDir)) || ".";
133
+ stdout.write("\nNext steps:\n");
134
+ if (rel !== ".") {
135
+ stdout.write(` cd ${rel}\n`);
136
+ }
137
+ if (!installRan) {
138
+ stdout.write(` ${packageManager} install\n`);
139
+ }
140
+ stdout.write(` ${packageManager} start\n`);
141
+ }
142
+ async function main() {
143
+ const options = parseArgs(process.argv.slice(2));
144
+ if (options.help) {
145
+ printHelp();
146
+ return;
147
+ }
148
+ if (options.listTemplates) {
149
+ printTemplates();
150
+ return;
151
+ }
152
+ const rl = createInterface({ input: stdin, output: stdout });
153
+ try {
154
+ const targetDir = options.targetDir || (await promptText(rl, "Project name", "rezi-app"));
155
+ const templateInput = options.template || (await promptTemplate(rl));
156
+ const templateKey = normalizeTemplateName(templateInput);
157
+ if (!templateKey) {
158
+ stdout.write(`\nUnknown template: ${templateInput}\n`);
159
+ printTemplates();
160
+ throw new Error("Invalid template");
161
+ }
162
+ const rawName = resolveTargetName(targetDir);
163
+ const displayName = toDisplayName(rawName);
164
+ const packageName = toValidPackageName(rawName);
165
+ if (!isValidPackageName(rawName)) {
166
+ stdout.write(`\nUsing package name: ${packageName}\n`);
167
+ }
168
+ const packageManager = resolvePackageManager(options.packageManager);
169
+ stdout.write(`\nCreating Rezi app in ${targetDir}...\n`);
170
+ await createProject({
171
+ targetDir,
172
+ templateKey,
173
+ packageName,
174
+ displayName,
175
+ });
176
+ if (options.install) {
177
+ stdout.write(`\nInstalling dependencies with ${packageManager}...\n`);
178
+ runInstall(packageManager, targetDir);
179
+ }
180
+ printNextSteps(targetDir, packageManager, options.install);
181
+ }
182
+ finally {
183
+ rl.close();
184
+ }
185
+ }
186
+ const isMain = process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1]);
187
+ if (isMain) {
188
+ main().catch((err) => {
189
+ stdout.write(`\ncreate-rezi error: ${err instanceof Error ? err.message : String(err)}\n`);
190
+ exit(1);
191
+ });
192
+ }
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type TemplateKey = "dashboard" | "form-app" | "file-browser" | "streaming-viewer";
2
+ export type TemplateDefinition = {
3
+ key: TemplateKey;
4
+ label: string;
5
+ description: string;
6
+ dir: string;
7
+ };
8
+ export declare const TEMPLATE_DEFINITIONS: readonly TemplateDefinition[];
9
+ export declare function normalizeTemplateName(value: string): TemplateKey | null;
10
+ export declare function toDisplayName(value: string): string;
11
+ export declare function isValidPackageName(name: string): boolean;
12
+ export declare function toValidPackageName(name: string): string;
13
+ export declare function resolveTargetName(targetDir: string): string;
14
+ export declare function getTemplatesRoot(): string;
15
+ export declare function ensureEmptyDir(dir: string): Promise<void>;
16
+ export type CreateProjectOptions = {
17
+ targetDir: string;
18
+ templateKey: TemplateKey;
19
+ packageName: string;
20
+ displayName: string;
21
+ };
22
+ export type CreateProjectResult = {
23
+ targetDir: string;
24
+ template: TemplateDefinition;
25
+ packageName: string;
26
+ displayName: string;
27
+ };
28
+ export declare function createProject(options: CreateProjectOptions): Promise<CreateProjectResult>;
29
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAEzF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,SAAS,kBAAkB,EAyBpD,CAAC;AAMX,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAyBvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWvD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB/D;AA+BD,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyB/F"}
@@ -0,0 +1,155 @@
1
+ import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
2
+ import { basename, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ export const TEMPLATE_DEFINITIONS = [
5
+ {
6
+ key: "dashboard",
7
+ label: "Dashboard",
8
+ description: "Multi-panel ops dashboard with status list",
9
+ dir: "dashboard",
10
+ },
11
+ {
12
+ key: "form-app",
13
+ label: "Form app",
14
+ description: "Data entry flow with preview panel",
15
+ dir: "form-app",
16
+ },
17
+ {
18
+ key: "file-browser",
19
+ label: "File browser",
20
+ description: "Split view with directory list + preview",
21
+ dir: "file-browser",
22
+ },
23
+ {
24
+ key: "streaming-viewer",
25
+ label: "Streaming viewer",
26
+ description: "Live stream list with chat + metrics",
27
+ dir: "streaming-viewer",
28
+ },
29
+ ];
30
+ const TEMPLATE_BY_KEY = new Map(TEMPLATE_DEFINITIONS.map((template) => [template.key, template]));
31
+ const PACKAGE_NAME_RE = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
32
+ export function normalizeTemplateName(value) {
33
+ const cleaned = value.trim().toLowerCase();
34
+ if (!cleaned)
35
+ return null;
36
+ const slug = cleaned.replace(/[\s_]+/g, "-");
37
+ switch (slug) {
38
+ case "dashboard":
39
+ return "dashboard";
40
+ case "form":
41
+ case "form-app":
42
+ case "formapp":
43
+ return "form-app";
44
+ case "file":
45
+ case "files":
46
+ case "file-browser":
47
+ case "filebrowser":
48
+ return "file-browser";
49
+ case "stream":
50
+ case "streaming":
51
+ case "streaming-viewer":
52
+ case "streamingviewer":
53
+ return "streaming-viewer";
54
+ default:
55
+ return TEMPLATE_BY_KEY.has(slug) ? slug : null;
56
+ }
57
+ }
58
+ export function toDisplayName(value) {
59
+ const name = value.trim();
60
+ if (!name)
61
+ return "Rezi App";
62
+ const parts = name.split(/[\s_-]+/).filter(Boolean);
63
+ if (parts.length === 0)
64
+ return "Rezi App";
65
+ return parts.map((part) => part[0]?.toUpperCase() + part.slice(1)).join(" ");
66
+ }
67
+ export function isValidPackageName(name) {
68
+ return PACKAGE_NAME_RE.test(name);
69
+ }
70
+ export function toValidPackageName(name) {
71
+ const trimmed = name.trim().toLowerCase();
72
+ if (isValidPackageName(trimmed))
73
+ return trimmed;
74
+ const sanitized = trimmed
75
+ .replace(/[^a-z0-9-._~@/]+/g, "-")
76
+ .replace(/\/+/, "/")
77
+ .replace(/\/+$/, "")
78
+ .replace(/^-+/, "")
79
+ .replace(/-+$/, "");
80
+ if (isValidPackageName(sanitized))
81
+ return sanitized;
82
+ return "rezi-app";
83
+ }
84
+ export function resolveTargetName(targetDir) {
85
+ const resolved = resolve(targetDir);
86
+ const base = basename(resolved);
87
+ return base || "rezi-app";
88
+ }
89
+ export function getTemplatesRoot() {
90
+ return fileURLToPath(new URL("../templates", import.meta.url));
91
+ }
92
+ export async function ensureEmptyDir(dir) {
93
+ try {
94
+ const stats = await stat(dir);
95
+ if (!stats.isDirectory()) {
96
+ throw new Error(`Target path exists and is not a directory: ${dir}`);
97
+ }
98
+ const entries = await readdir(dir);
99
+ if (entries.length > 0) {
100
+ throw new Error(`Target directory is not empty: ${dir}`);
101
+ }
102
+ }
103
+ catch (err) {
104
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
105
+ await mkdir(dir, { recursive: true });
106
+ return;
107
+ }
108
+ throw err;
109
+ }
110
+ }
111
+ function applySubstitutions(content, vars) {
112
+ let out = content;
113
+ for (const [key, value] of Object.entries(vars)) {
114
+ out = out.replaceAll(`__${key}__`, value);
115
+ }
116
+ return out;
117
+ }
118
+ async function copyTemplateDir(sourceDir, targetDir, vars) {
119
+ await mkdir(targetDir, { recursive: true });
120
+ const entries = await readdir(sourceDir, { withFileTypes: true });
121
+ for (const entry of entries) {
122
+ const srcPath = join(sourceDir, entry.name);
123
+ const destPath = join(targetDir, entry.name);
124
+ if (entry.isDirectory()) {
125
+ await copyTemplateDir(srcPath, destPath, vars);
126
+ continue;
127
+ }
128
+ const raw = await readFile(srcPath, "utf8");
129
+ const next = applySubstitutions(raw, vars);
130
+ await writeFile(destPath, next, "utf8");
131
+ }
132
+ }
133
+ export async function createProject(options) {
134
+ const template = TEMPLATE_BY_KEY.get(options.templateKey);
135
+ if (!template) {
136
+ throw new Error(`Unknown template: ${options.templateKey}`);
137
+ }
138
+ await ensureEmptyDir(options.targetDir);
139
+ const templatesRoot = getTemplatesRoot();
140
+ const sourceDir = join(templatesRoot, template.dir);
141
+ const vars = {
142
+ APP_NAME: options.displayName,
143
+ PACKAGE_NAME: options.packageName,
144
+ TEMPLATE_LABEL: template.label,
145
+ TEMPLATE_KEY: template.key,
146
+ };
147
+ await copyTemplateDir(sourceDir, options.targetDir, vars);
148
+ return {
149
+ targetDir: options.targetDir,
150
+ template,
151
+ packageName: options.packageName,
152
+ displayName: options.displayName,
153
+ };
154
+ }
155
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "create-rezi",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Scaffold a Rezi terminal UI app.",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://rtlzeromemory.github.io/Rezi/",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/RtlZeroMemory/Rezi.git",
10
+ "directory": "packages/create-rezi"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/RtlZeroMemory/Rezi/issues"
14
+ },
15
+ "type": "module",
16
+ "bin": {
17
+ "create-rezi": "dist/index.js"
18
+ },
19
+ "files": [
20
+ "dist/",
21
+ "templates/",
22
+ "README.md"
23
+ ],
24
+ "engines": {
25
+ "node": ">=18"
26
+ },
27
+ "devDependencies": {
28
+ "@rezi-ui/testkit": "0.1.0-alpha.1"
29
+ }
30
+ }
@@ -0,0 +1,18 @@
1
+ # __APP_NAME__
2
+
3
+ Scaffolded with `npm create rezi` using the **__TEMPLATE_LABEL__** template.
4
+
5
+ ## Quickstart
6
+
7
+ ```bash
8
+ npm install
9
+ npm start
10
+ ```
11
+
12
+ ## Keybindings
13
+
14
+ - `up` / `down` or `j` / `k`: Move selection
15
+ - `f`: Cycle filter
16
+ - `enter`: Pin service
17
+ - `?`: Toggle help
18
+ - `q`: Quit
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "__PACKAGE_NAME__",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "tsx src/main.ts",
8
+ "dev": "tsx watch src/main.ts",
9
+ "typecheck": "tsc --noEmit"
10
+ },
11
+ "dependencies": {
12
+ "@rezi-ui/core": "^0.1.0-alpha.0",
13
+ "@rezi-ui/node": "^0.1.0-alpha.0"
14
+ },
15
+ "devDependencies": {
16
+ "@types/node": "^22.13.1",
17
+ "tsx": "^4.20.0",
18
+ "typescript": "^5.6.3"
19
+ },
20
+ "engines": {
21
+ "node": ">=18"
22
+ }
23
+ }