create-rigg 0.0.7 → 0.1.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 +4 -4
- package/dist/index.mjs +99 -78
- package/package.json +16 -15
- package/template/package.json +9 -1
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
<a href="https://www.npmjs.com/package/create-rigg"><img src="https://img.shields.io/npm/v/create-rigg.svg" alt="Version"></a>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
|
-
**Create Node.js projects with a
|
|
8
|
+
**Create Node.js projects with a modern toolchain**
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
I really like what [VoidZero](https://voidzero.dev) and [Vite+](https://github.com/voidzero-dev/vite-plus) are doing for web development. **rigg** brings the same toolchain to every Node.js project outside the browser. Use it for backends, CLIs, libraries, scripts, whatever you're building.
|
|
11
11
|
|
|
12
12
|
## Create a new project with rigg
|
|
13
13
|
|
|
@@ -18,15 +18,15 @@ npm create rigg@latest
|
|
|
18
18
|
|
|
19
19
|
## What you get
|
|
20
20
|
|
|
21
|
-
A project created with rigg gets most of the same tools
|
|
21
|
+
A project created with rigg gets most of the same tools as in the Vite+ toolchain.
|
|
22
22
|
|
|
23
23
|
| Tool | Role |
|
|
24
24
|
| -------------------------------------------------- | ------------------ |
|
|
25
25
|
| [Vitest](https://vitest.dev) | Testing |
|
|
26
26
|
| [Oxlint](https://oxc.rs/docs/guide/usage/linter) | Linting |
|
|
27
27
|
| [Oxfmt](https://oxc.rs/docs/guide/usage/formatter) | Formatting |
|
|
28
|
-
| [tsx](https://tsx.is) | Dev-mode execution |
|
|
29
28
|
| [tsdown](https://tsdown.dev) | Build |
|
|
29
|
+
| [tsx](https://tsx.is) | Dev-mode execution |
|
|
30
30
|
|
|
31
31
|
### Backend framework
|
|
32
32
|
|
package/dist/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ const FRAMEWORKS = [
|
|
|
15
15
|
{
|
|
16
16
|
value: "hono",
|
|
17
17
|
label: "Hono",
|
|
18
|
-
hint: "recommended"
|
|
18
|
+
hint: "recommended framework"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
value: "fastify",
|
|
@@ -50,6 +50,7 @@ const FRAMEWORK_DEPS = {
|
|
|
50
50
|
devDeps: ["@types/express"]
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
+
/** Starter code (index.ts) for each framework. */
|
|
53
54
|
const FRAMEWORK_INDEX = {
|
|
54
55
|
none: `console.log('Hello from rigg!')\n`,
|
|
55
56
|
hono: `import { Hono } from 'hono'
|
|
@@ -65,22 +66,36 @@ serve(app, (info) => {
|
|
|
65
66
|
`,
|
|
66
67
|
fastify: `import Fastify from 'fastify'
|
|
67
68
|
|
|
68
|
-
const fastify = Fastify({
|
|
69
|
+
const fastify = Fastify({
|
|
70
|
+
logger: true,
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
fastify.get('/', async (request, reply) => {
|
|
74
|
+
return { hello: 'world' }
|
|
75
|
+
})
|
|
69
76
|
|
|
70
|
-
|
|
77
|
+
const start = async () => {
|
|
78
|
+
try {
|
|
79
|
+
await fastify.listen({ port: 3000 })
|
|
80
|
+
} catch (err) {
|
|
81
|
+
fastify.log.error(err)
|
|
82
|
+
process.exit(1)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
71
85
|
|
|
72
|
-
|
|
86
|
+
start()
|
|
73
87
|
`,
|
|
74
88
|
express: `import express from 'express'
|
|
75
89
|
|
|
76
90
|
const app = express()
|
|
91
|
+
const port = 3000
|
|
77
92
|
|
|
78
93
|
app.get('/', (req, res) => {
|
|
79
94
|
res.send('Hello World')
|
|
80
95
|
})
|
|
81
96
|
|
|
82
|
-
app.listen(
|
|
83
|
-
console.log(
|
|
97
|
+
app.listen(port, () => {
|
|
98
|
+
console.log(\`Server running on http://localhost:\${port}\`)
|
|
84
99
|
})
|
|
85
100
|
`
|
|
86
101
|
};
|
|
@@ -94,6 +109,15 @@ const PKG_MANAGERS = [
|
|
|
94
109
|
];
|
|
95
110
|
//#endregion
|
|
96
111
|
//#region src/index.ts
|
|
112
|
+
const THEME = [[
|
|
113
|
+
251,
|
|
114
|
+
146,
|
|
115
|
+
60
|
|
116
|
+
], [
|
|
117
|
+
236,
|
|
118
|
+
72,
|
|
119
|
+
153
|
|
120
|
+
]];
|
|
97
121
|
/** Creates a colored gradient text effect */
|
|
98
122
|
function gradient(text, stops, whiteRange) {
|
|
99
123
|
const chars = [...text];
|
|
@@ -127,17 +151,22 @@ function addArgs(pkgManager, packages, dev) {
|
|
|
127
151
|
...packages
|
|
128
152
|
] : [cmd, ...packages];
|
|
129
153
|
}
|
|
130
|
-
/** Runs a command
|
|
154
|
+
/** Runs a command asynchronously, exiting the process if it fails. */
|
|
131
155
|
function run(cmd, args, opts) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const result = spawn(cmd, args, {
|
|
158
|
+
stdio: "ignore",
|
|
159
|
+
...opts
|
|
160
|
+
});
|
|
161
|
+
result.on("error", reject);
|
|
162
|
+
result.on("close", (code) => {
|
|
163
|
+
if (code !== 0) {
|
|
164
|
+
p.cancel(`${cmd} ${args.join(" ")} failed with exit code ${code}`);
|
|
165
|
+
process.exit(code ?? 1);
|
|
166
|
+
}
|
|
167
|
+
resolve();
|
|
168
|
+
});
|
|
135
169
|
});
|
|
136
|
-
if (result.error) throw result.error;
|
|
137
|
-
if (result.status != null && result.status !== 0) {
|
|
138
|
-
p.cancel(`${cmd} ${args.join(" ")} failed with exit code ${result.status}`);
|
|
139
|
-
process.exit(result.status);
|
|
140
|
-
}
|
|
141
170
|
}
|
|
142
171
|
/** Recursively copies a directory, renaming _gitignore to .gitignore. */
|
|
143
172
|
function copyDir(src, dest) {
|
|
@@ -194,36 +223,38 @@ async function confirmOverwrite(projectName, targetDir) {
|
|
|
194
223
|
p.cancel("Cancelled");
|
|
195
224
|
process.exit(0);
|
|
196
225
|
}
|
|
197
|
-
|
|
226
|
+
const spin = p.spinner();
|
|
227
|
+
spin.start("Removing existing files...");
|
|
228
|
+
await fs.promises.rm(targetDir, {
|
|
198
229
|
recursive: true,
|
|
199
230
|
force: true
|
|
200
231
|
});
|
|
232
|
+
spin.stop("Removed existing files");
|
|
201
233
|
}
|
|
202
234
|
/** Copies the base template, sets the package name, and writes the framework starter code. */
|
|
203
|
-
function scaffoldFiles(options, targetDir) {
|
|
235
|
+
async function scaffoldFiles(options, targetDir) {
|
|
236
|
+
const spin = p.spinner();
|
|
237
|
+
spin.start("Generating project...");
|
|
238
|
+
/** Copy the base template to the target directory. */
|
|
204
239
|
const directory = path.dirname(fileURLToPath(import.meta.url));
|
|
205
240
|
copyDir(path.join(directory, "..", "template"), targetDir);
|
|
241
|
+
/** Set the package name in the package.json file. */
|
|
206
242
|
const pkgJsonPath = path.join(targetDir, "package.json");
|
|
207
243
|
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
208
244
|
pkg.name = options.projectName;
|
|
209
245
|
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
246
|
+
/** Create the src directory and write the framework starter code. */
|
|
210
247
|
fs.mkdirSync(path.join(targetDir, "src"), { recursive: true });
|
|
211
248
|
fs.writeFileSync(path.join(targetDir, "src", "index.ts"), FRAMEWORK_INDEX[options.framework]);
|
|
249
|
+
spin.stop("Project generated");
|
|
212
250
|
}
|
|
213
251
|
/** Installs shared dev dependencies and any framework-specific packages. */
|
|
214
|
-
function installDependencies(options, targetDir) {
|
|
252
|
+
async function installDependencies(options, targetDir) {
|
|
215
253
|
const { pkgManager, framework, verbose } = options;
|
|
216
254
|
const stdio = verbose ? "inherit" : "ignore";
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
247
|
|
221
|
-
], [
|
|
222
|
-
99,
|
|
223
|
-
102,
|
|
224
|
-
241
|
|
225
|
-
]])}...`);
|
|
226
|
-
run(pkgManager, addArgs(pkgManager, [
|
|
255
|
+
const depSpin = p.spinner();
|
|
256
|
+
depSpin.start(`Installing dependencies with ${gradient(pkgManager, THEME)}...`);
|
|
257
|
+
await run(pkgManager, addArgs(pkgManager, [
|
|
227
258
|
"@types/node",
|
|
228
259
|
"oxfmt",
|
|
229
260
|
"oxlint",
|
|
@@ -235,64 +266,42 @@ function installDependencies(options, targetDir) {
|
|
|
235
266
|
cwd: targetDir,
|
|
236
267
|
stdio
|
|
237
268
|
});
|
|
269
|
+
depSpin.stop(`Dependencies installed with ${gradient(pkgManager, THEME)}`);
|
|
238
270
|
if (framework !== "none") {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
247
|
|
243
|
-
], [
|
|
244
|
-
99,
|
|
245
|
-
102,
|
|
246
|
-
241
|
|
247
|
-
]])}...`);
|
|
271
|
+
const frameworkName = FRAMEWORK_LABELS[framework];
|
|
272
|
+
const frameworkSpin = p.spinner();
|
|
273
|
+
frameworkSpin.start(`Installing ${gradient(frameworkName, THEME)}...`);
|
|
248
274
|
const { deps, devDeps } = FRAMEWORK_DEPS[framework];
|
|
249
|
-
if (deps.length > 0) run(pkgManager, addArgs(pkgManager, deps, false), {
|
|
275
|
+
if (deps.length > 0) await run(pkgManager, addArgs(pkgManager, deps, false), {
|
|
250
276
|
cwd: targetDir,
|
|
251
277
|
stdio
|
|
252
278
|
});
|
|
253
|
-
if (devDeps.length > 0) run(pkgManager, addArgs(pkgManager, devDeps, true), {
|
|
279
|
+
if (devDeps.length > 0) await run(pkgManager, addArgs(pkgManager, devDeps, true), {
|
|
254
280
|
cwd: targetDir,
|
|
255
281
|
stdio
|
|
256
282
|
});
|
|
283
|
+
frameworkSpin.stop(`${gradient(frameworkName, THEME)} installed`);
|
|
257
284
|
}
|
|
258
285
|
}
|
|
259
286
|
/** Prints the gradient intro. */
|
|
260
287
|
function showIntro() {
|
|
261
|
-
p.intro(pc.bold(gradient("rigg -
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
],
|
|
267
|
-
[
|
|
268
|
-
168,
|
|
269
|
-
85,
|
|
270
|
-
247
|
|
271
|
-
],
|
|
272
|
-
[
|
|
273
|
-
99,
|
|
274
|
-
102,
|
|
275
|
-
241
|
|
276
|
-
]
|
|
277
|
-
], [0, 6])));
|
|
288
|
+
p.intro(pc.bold(gradient("rigg - Node.js projects with a modern toolchain", [[
|
|
289
|
+
255,
|
|
290
|
+
255,
|
|
291
|
+
255
|
|
292
|
+
], ...THEME], [0, 6])));
|
|
278
293
|
}
|
|
279
294
|
/** Prints the gradient outro with next steps. */
|
|
280
295
|
function showOutro(options) {
|
|
281
296
|
const { projectName, framework, pkgManager } = options;
|
|
282
297
|
const frameworkLabel = FRAMEWORK_LABELS[framework];
|
|
283
|
-
const title = gradient(frameworkLabel !== "None" ? `Created ${projectName} with ${frameworkLabel}` : `Created ${projectName}`, [
|
|
284
|
-
168,
|
|
285
|
-
85,
|
|
286
|
-
247
|
|
287
|
-
], [
|
|
288
|
-
99,
|
|
289
|
-
102,
|
|
290
|
-
241
|
|
291
|
-
]], [8, 8 + projectName.length]);
|
|
298
|
+
const title = gradient(frameworkLabel !== "None" ? `Created ${projectName} with ${frameworkLabel}` : `Created ${projectName}`, THEME, [8, 8 + projectName.length]);
|
|
292
299
|
const devCmd = pkgManager === "npm" ? "npm run dev" : `${pkgManager} dev`;
|
|
293
300
|
p.outro(`${title}\n\n ${pc.dim("Now run:")}\n cd ${projectName}\n ${devCmd}`);
|
|
294
301
|
}
|
|
295
|
-
/**
|
|
302
|
+
/**
|
|
303
|
+
* Resolves options either from CLI args or user prompts.
|
|
304
|
+
*/
|
|
296
305
|
async function resolveOptions(argv) {
|
|
297
306
|
const projectName = await resolveProjectName(argv._[0]);
|
|
298
307
|
await confirmOverwrite(projectName, path.resolve(process.cwd(), projectName));
|
|
@@ -303,9 +312,15 @@ async function resolveOptions(argv) {
|
|
|
303
312
|
verbose: argv.verbose ?? false
|
|
304
313
|
};
|
|
305
314
|
}
|
|
306
|
-
function initializeGit(options, targetDir) {
|
|
307
|
-
|
|
308
|
-
|
|
315
|
+
async function initializeGit(options, targetDir) {
|
|
316
|
+
const git = spawn.sync("git", ["--version"], { stdio: "ignore" });
|
|
317
|
+
if (git.error || git.status !== 0) {
|
|
318
|
+
p.log.info("Git not found. Skipping repository initialization.");
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const spin = p.spinner();
|
|
322
|
+
spin.start("Initializing git repository...");
|
|
323
|
+
await run("git", [
|
|
309
324
|
"init",
|
|
310
325
|
"-b",
|
|
311
326
|
"main"
|
|
@@ -313,14 +328,19 @@ function initializeGit(options, targetDir) {
|
|
|
313
328
|
cwd: targetDir,
|
|
314
329
|
stdio: options.verbose ? "inherit" : "ignore"
|
|
315
330
|
});
|
|
331
|
+
spin.stop("Git repository initialized");
|
|
316
332
|
}
|
|
317
|
-
|
|
318
|
-
|
|
333
|
+
/**
|
|
334
|
+
* Creates oxlint+oxfmt configuration files and formats the code.
|
|
335
|
+
*/
|
|
336
|
+
async function formatCode(options, targetDir) {
|
|
319
337
|
const { pkgManager, verbose } = options;
|
|
320
338
|
const stdio = verbose ? "inherit" : "ignore";
|
|
321
339
|
const execCmd = pkgManager === "bun" ? "x" : "exec";
|
|
322
340
|
const sep = pkgManager === "npm" || pkgManager === "yarn" ? ["--"] : [];
|
|
323
|
-
|
|
341
|
+
const spin = p.spinner();
|
|
342
|
+
spin.start("Formatting code...");
|
|
343
|
+
await run(pkgManager, [
|
|
324
344
|
execCmd,
|
|
325
345
|
"oxlint",
|
|
326
346
|
...sep,
|
|
@@ -329,7 +349,7 @@ function formatCode(options, targetDir) {
|
|
|
329
349
|
cwd: targetDir,
|
|
330
350
|
stdio
|
|
331
351
|
});
|
|
332
|
-
run(pkgManager, [
|
|
352
|
+
await run(pkgManager, [
|
|
333
353
|
execCmd,
|
|
334
354
|
"oxfmt",
|
|
335
355
|
...sep,
|
|
@@ -338,7 +358,7 @@ function formatCode(options, targetDir) {
|
|
|
338
358
|
cwd: targetDir,
|
|
339
359
|
stdio
|
|
340
360
|
});
|
|
341
|
-
run(pkgManager, [
|
|
361
|
+
await run(pkgManager, [
|
|
342
362
|
execCmd,
|
|
343
363
|
"oxfmt",
|
|
344
364
|
...sep,
|
|
@@ -347,6 +367,7 @@ function formatCode(options, targetDir) {
|
|
|
347
367
|
cwd: targetDir,
|
|
348
368
|
stdio
|
|
349
369
|
});
|
|
370
|
+
spin.stop("Code formatted");
|
|
350
371
|
}
|
|
351
372
|
async function main() {
|
|
352
373
|
const argv = mri(process.argv.slice(2), {
|
|
@@ -360,10 +381,10 @@ async function main() {
|
|
|
360
381
|
showIntro();
|
|
361
382
|
const options = await resolveOptions(argv);
|
|
362
383
|
const targetDir = path.resolve(process.cwd(), options.projectName);
|
|
363
|
-
scaffoldFiles(options, targetDir);
|
|
364
|
-
initializeGit(options, targetDir);
|
|
365
|
-
installDependencies(options, targetDir);
|
|
366
|
-
formatCode(options, targetDir);
|
|
384
|
+
await scaffoldFiles(options, targetDir);
|
|
385
|
+
await initializeGit(options, targetDir);
|
|
386
|
+
await installDependencies(options, targetDir);
|
|
387
|
+
await formatCode(options, targetDir);
|
|
367
388
|
showOutro(options);
|
|
368
389
|
}
|
|
369
390
|
main().catch((err) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-rigg",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Create Node.js TypeScript projects
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Create Node.js TypeScript projects using the Vite+ Toolchain - for everything outside the browser.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
7
7
|
"create-rigg",
|
|
@@ -38,17 +38,6 @@
|
|
|
38
38
|
"template"
|
|
39
39
|
],
|
|
40
40
|
"type": "module",
|
|
41
|
-
"scripts": {
|
|
42
|
-
"test": "vitest",
|
|
43
|
-
"lint": "oxlint",
|
|
44
|
-
"lint:fix": "oxlint --fix",
|
|
45
|
-
"fmt": "oxfmt",
|
|
46
|
-
"fmt:check": "oxfmt --check",
|
|
47
|
-
"check": "oxlint && oxfmt --check && tsc --noEmit",
|
|
48
|
-
"dev": "tsx src/index.ts",
|
|
49
|
-
"build": "tsdown src/index.ts",
|
|
50
|
-
"prepublishOnly": "git diff --exit-code && git diff --cached --exit-code && oxlint && oxfmt && tsc --noEmit && vitest run && pnpm build"
|
|
51
|
-
},
|
|
52
41
|
"dependencies": {
|
|
53
42
|
"@clack/prompts": "^1.1.0",
|
|
54
43
|
"cross-spawn": "^7.0.6",
|
|
@@ -65,5 +54,17 @@
|
|
|
65
54
|
"typescript": "^6.0.2",
|
|
66
55
|
"vitest": "^4.1.2"
|
|
67
56
|
},
|
|
68
|
-
"
|
|
69
|
-
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=22.12.0"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"test": "vitest",
|
|
62
|
+
"lint": "oxlint",
|
|
63
|
+
"lint:fix": "oxlint --fix",
|
|
64
|
+
"fmt": "oxfmt",
|
|
65
|
+
"fmt:check": "oxfmt --check",
|
|
66
|
+
"check": "oxlint && oxfmt --check && tsc --noEmit",
|
|
67
|
+
"dev": "tsx src/index.ts",
|
|
68
|
+
"build": "tsdown src/index.ts"
|
|
69
|
+
}
|
|
70
|
+
}
|
package/template/package.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
2
|
+
"name": "rigg-project",
|
|
3
3
|
"version": "0.0.0",
|
|
4
|
+
"description": "Create Node.js TypeScript projects with a Unified Toolchain",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"license": "",
|
|
7
|
+
"author": "",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "",
|
|
10
|
+
"url": ""
|
|
11
|
+
},
|
|
4
12
|
"type": "module",
|
|
5
13
|
"scripts": {
|
|
6
14
|
"dev": "tsx src/index.ts",
|