@raulmoracode/create 1.0.0 → 1.0.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/README.md +5 -21
- package/dist/cli/args.js +1 -6
- package/dist/cli/run.js +19 -32
- package/dist/config/agents.js +0 -1
- package/dist/config/tech.js +0 -13
- package/dist/generators/configure-project.js +0 -3
- package/package.json +2 -2
- package/dist/config/npmrc.js +0 -3
- package/dist/generators/configure-registry.js +0 -5
- package/dist/utils/registry.js +0 -18
package/README.md
CHANGED
|
@@ -13,7 +13,6 @@ Professional CLI to scaffold modern React projects. Built with Node.js, TypeScri
|
|
|
13
13
|
- npm
|
|
14
14
|
- [Git](https://git-scm.com/downloads) with a configured identity (`user.name` and `user.email`)
|
|
15
15
|
- A GitHub account and an existing empty repository for the new project
|
|
16
|
-
- `GH_TOKEN` (optional): only needed to install the private `@raulmoracode/icons` package. Without registry access, the project is generated without `.npmrc` and without icons — everything else is identical.
|
|
17
16
|
- [VS Code](https://code.visualstudio.com) (optional, used to open the project at the end)
|
|
18
17
|
|
|
19
18
|
## Install globally
|
|
@@ -62,8 +61,7 @@ raulmoracode-create --version # show the installed version
|
|
|
62
61
|
- Installs dependencies with **pnpm** and pins exact versions (no `^` or `~`).
|
|
63
62
|
- Configures **Tailwind CSS 4.3.3** (CSS-first configuration, `@tailwindcss/vite` for Vite and `@tailwindcss/postcss` for Next.js).
|
|
64
63
|
- Prepares **shadcn**: writes a complete `components.json` (including the `@raulmoracode` registry) and the `cn()` helper (`src/lib/utils.ts`). No components are preinstalled; add them later with `pnpm dlx shadcn@latest add <component>`.
|
|
65
|
-
-
|
|
66
|
-
- Installs **Zustand 5.0.15**, **React Hook Form 7.89.0**, **Zod 4.6.5**, **TanStack Query 5.104.0** and **@raulmoracode/icons 1.1.0**, and wires the TanStack Query provider.
|
|
64
|
+
- Installs **Zustand 5.0.15**, **React Hook Form 7.89.0**, **Zod 4.6.5** and **TanStack Query 5.104.0**, and wires the TanStack Query provider.
|
|
67
65
|
- Configures **Biome 2.5.14** (formatter, linter and organize imports) and removes the ESLint/Oxlint leftovers from the official templates.
|
|
68
66
|
- Configures **Vitest 5.0.2**, **@testing-library/react 16.3.3** and **@testing-library/dom 10.4.2** (plus `jsdom`, required by Testing Library, and `clsx` + `tailwind-merge`, required by the shadcn `cn()` helper).
|
|
69
67
|
- Configures **VS Code** (`.vscode/settings.json` and `.vscode/extensions.json`).
|
|
@@ -82,7 +80,6 @@ Every generated project includes:
|
|
|
82
80
|
- React + Vite or Next.js (official structure)
|
|
83
81
|
- Tailwind CSS 4
|
|
84
82
|
- shadcn ready (`components.json` with the `@raulmoracode` registry and the `cn()` helper)
|
|
85
|
-
- `@raulmoracode` registry in `.npmrc` (`${GH_TOKEN}`, only with registry access)
|
|
86
83
|
- Zustand
|
|
87
84
|
- React Hook Form + Zod
|
|
88
85
|
- TanStack Query (provider included)
|
|
@@ -107,7 +104,7 @@ pnpm format
|
|
|
107
104
|
pnpm lint
|
|
108
105
|
```
|
|
109
106
|
|
|
110
|
-
Add shadcn components
|
|
107
|
+
Add shadcn components:
|
|
111
108
|
|
|
112
109
|
```bash
|
|
113
110
|
pnpm dlx shadcn@latest add card
|
|
@@ -130,21 +127,6 @@ The CLI runs `git push -u origin main`, so Git must be authenticated against Git
|
|
|
130
127
|
|
|
131
128
|
- [GitHub CLI](https://cli.github.com): `gh auth login`
|
|
132
129
|
- A credential manager / SSH key configured for `github.com`
|
|
133
|
-
- A `GH_TOKEN` / `GITHUB_TOKEN` environment variable together with a credential helper
|
|
134
|
-
|
|
135
|
-
### Note on `GH_TOKEN` and pnpm >= 11.5.3
|
|
136
|
-
|
|
137
|
-
The generated `.npmrc` references `${GH_TOKEN}` as mandated. However, since **pnpm 11.5.3** environment variables are **not** expanded in project-level `.npmrc` credential values (a security fix for [GHSA-3qhv-2rgh-x77r](https://github.com/pnpm/security/advisories/GHSA-3qhv-2rgh-x77r)): pnpm prints a warning and ignores that line, while the registry mapping (`@raulmoracode:registry=...`) still applies. To authenticate installs from GitHub Packages, keep your token in a **user-level** location where expansion works:
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
pnpm config set //npm.pkg.github.com/:_authToken "$GH_TOKEN"
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
or in `~/.npmrc`:
|
|
144
|
-
|
|
145
|
-
```ini
|
|
146
|
-
//npm.pkg.github.com/:_authToken=${GH_TOKEN}
|
|
147
|
-
```
|
|
148
130
|
|
|
149
131
|
## npm
|
|
150
132
|
|
|
@@ -220,10 +202,12 @@ The following deviations from the naive expected configuration were verified aga
|
|
|
220
202
|
```bash
|
|
221
203
|
pnpm build
|
|
222
204
|
npm pack
|
|
223
|
-
npm install -g ./raulmoracode-create
|
|
205
|
+
npm install -g ./raulmoracode-create-*.tgz
|
|
224
206
|
raulmoracode-create
|
|
225
207
|
```
|
|
226
208
|
|
|
209
|
+
The glob keeps working across versions: `npm pack` names the tarball after the current `package.json` version, so a hardcoded name would go stale on every release.
|
|
210
|
+
|
|
227
211
|
The packaged tarball contains `dist/` (including the `raulmoracode-create` bin with its shebang), `README.md` and `LICENSE`.
|
|
228
212
|
|
|
229
213
|
## License
|
package/dist/cli/args.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const VERSION = "1.0.
|
|
1
|
+
export const VERSION = "1.0.2";
|
|
2
2
|
export function parseArgs(argv) {
|
|
3
3
|
return {
|
|
4
4
|
help: argv.includes("--help") || argv.includes("-h"),
|
|
@@ -18,11 +18,6 @@ export function helpText() {
|
|
|
18
18
|
" -h, --help Show this help message.",
|
|
19
19
|
" -V, --version Show the installed version.",
|
|
20
20
|
"",
|
|
21
|
-
"Environment:",
|
|
22
|
-
" GH_TOKEN (optional) Enables the private @raulmoracode/icons package.",
|
|
23
|
-
" Without registry access the project is generated",
|
|
24
|
-
" without .npmrc and without icons.",
|
|
25
|
-
"",
|
|
26
21
|
"Examples:",
|
|
27
22
|
" raulmoracode-create",
|
|
28
23
|
" raulmoracode-create --verbose",
|
package/dist/cli/run.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { intro, log, tasks } from "@clack/prompts";
|
|
2
|
-
import { applyPrivateAccess } from "../config/tech.js";
|
|
3
2
|
import { getFramework } from "../frameworks/index.js";
|
|
4
3
|
import { configureBiome, formatProject, } from "../generators/configure-biome.js";
|
|
5
4
|
import { configureGitHooks } from "../generators/configure-git-hooks.js";
|
|
6
5
|
import { augmentGitignore, configureEditorconfig, configureNode, } from "../generators/configure-node.js";
|
|
7
6
|
import { installDependencies, normalizePackageJson, patchPackageJson, refreshPnpmWorkspaceExcludes, } from "../generators/configure-project.js";
|
|
8
|
-
import { configureRegistry } from "../generators/configure-registry.js";
|
|
9
7
|
import { configureShadcn } from "../generators/configure-shadcn.js";
|
|
10
8
|
import { configureTesting } from "../generators/configure-testing.js";
|
|
11
9
|
import { configureVscode } from "../generators/configure-vscode.js";
|
|
@@ -21,7 +19,6 @@ import { promptProjectName } from "../prompts/project.js";
|
|
|
21
19
|
import { promptTechPreset } from "../prompts/tech.js";
|
|
22
20
|
import { ExecError, exec } from "../utils/exec.js";
|
|
23
21
|
import { ensureDir, isDirectoryEmpty, pathExists, removeEmptyDir, removeIfExists, resolvePath, } from "../utils/filesystem.js";
|
|
24
|
-
import { checkPrivateRegistryAccess } from "../utils/registry.js";
|
|
25
22
|
import { satisfiesNodeVersion } from "../utils/validation.js";
|
|
26
23
|
import { showFarewell, showSummary, showWarning } from "./output.js";
|
|
27
24
|
const MINIMUM_NODE_MAJOR = 24;
|
|
@@ -123,12 +120,6 @@ export async function run(options = {}) {
|
|
|
123
120
|
cleanupDir = projectDir;
|
|
124
121
|
restoreEmptyDir = reusedEmptyDir;
|
|
125
122
|
await checkRemoteAccess(githubUrl, verbose);
|
|
126
|
-
const hasPrivateAccess = await checkPrivateRegistryAccess();
|
|
127
|
-
const effectiveSelection = applyPrivateAccess(selection, hasPrivateAccess);
|
|
128
|
-
if (selection.registry && !hasPrivateAccess) {
|
|
129
|
-
showWarning("Sin acceso al registro privado @raulmoracode (GH_TOKEN ausente o sin permisos): " +
|
|
130
|
-
"se omite @raulmoracode/icons y el .npmrc.");
|
|
131
|
-
}
|
|
132
123
|
const framework = getFramework(frameworkId);
|
|
133
124
|
await tasks([
|
|
134
125
|
{
|
|
@@ -137,21 +128,17 @@ export async function run(options = {}) {
|
|
|
137
128
|
failedStep = "Creating project";
|
|
138
129
|
message(`Scaffolding with ${framework.label}`);
|
|
139
130
|
await createProject(framework, projectName, process.cwd(), verbose);
|
|
140
|
-
if (
|
|
131
|
+
if (selection.tailwind) {
|
|
141
132
|
message("Configuring Tailwind CSS");
|
|
142
133
|
await framework.configureTailwind(projectDir);
|
|
143
134
|
}
|
|
144
135
|
message("Configuring branding");
|
|
145
136
|
await framework.configureBranding(projectDir);
|
|
146
|
-
if (
|
|
137
|
+
if (selection.shadcn) {
|
|
147
138
|
message("Configuring shadcn");
|
|
148
139
|
await configureShadcn(projectDir, framework);
|
|
149
140
|
}
|
|
150
|
-
if (
|
|
151
|
-
message("Configuring @raulmoracode registry");
|
|
152
|
-
await configureRegistry(projectDir);
|
|
153
|
-
}
|
|
154
|
-
if (effectiveSelection["tanstack-query"]) {
|
|
141
|
+
if (selection["tanstack-query"]) {
|
|
155
142
|
message("Configuring TanStack Query");
|
|
156
143
|
await framework.configureTanStackQuery(projectDir);
|
|
157
144
|
}
|
|
@@ -159,26 +146,26 @@ export async function run(options = {}) {
|
|
|
159
146
|
message("Configuring starter");
|
|
160
147
|
await framework.configureStarter(projectDir);
|
|
161
148
|
}
|
|
162
|
-
if (
|
|
149
|
+
if (selection.biome) {
|
|
163
150
|
message("Configuring Biome");
|
|
164
151
|
await configureBiome(projectDir);
|
|
165
152
|
}
|
|
166
|
-
if (
|
|
153
|
+
if (selection.testing) {
|
|
167
154
|
message("Configuring testing");
|
|
168
155
|
await configureTesting(projectDir);
|
|
169
156
|
}
|
|
170
|
-
if (
|
|
157
|
+
if (selection.vscode) {
|
|
171
158
|
message("Configuring VS Code");
|
|
172
159
|
await configureVscode(projectDir);
|
|
173
160
|
}
|
|
174
161
|
message("Configuring Node version");
|
|
175
162
|
await configureNode(projectDir);
|
|
176
163
|
await configureEditorconfig(projectDir);
|
|
177
|
-
if (
|
|
164
|
+
if (selection.husky) {
|
|
178
165
|
message("Configuring Git hooks");
|
|
179
|
-
await configureGitHooks(projectDir,
|
|
166
|
+
await configureGitHooks(projectDir, selection);
|
|
180
167
|
}
|
|
181
|
-
await patchPackageJson(projectDir, framework, projectName, githubUrl,
|
|
168
|
+
await patchPackageJson(projectDir, framework, projectName, githubUrl, selection);
|
|
182
169
|
await augmentGitignore(projectDir);
|
|
183
170
|
return "Project created";
|
|
184
171
|
},
|
|
@@ -188,30 +175,30 @@ export async function run(options = {}) {
|
|
|
188
175
|
task: async (message) => {
|
|
189
176
|
failedStep = "Installing dependencies";
|
|
190
177
|
message("Installing base and additional dependencies");
|
|
191
|
-
await installDependencies(projectDir, framework, verbose,
|
|
178
|
+
await installDependencies(projectDir, framework, verbose, selection);
|
|
192
179
|
await normalizePackageJson(projectDir);
|
|
193
|
-
if (
|
|
180
|
+
if (selection.biome) {
|
|
194
181
|
message("Formatting project with Biome");
|
|
195
182
|
await formatProject(projectDir, verbose);
|
|
196
183
|
}
|
|
197
184
|
message("Configuring pnpm workspace");
|
|
198
|
-
await refreshPnpmWorkspaceExcludes(projectDir, framework, verbose,
|
|
199
|
-
if (
|
|
185
|
+
await refreshPnpmWorkspaceExcludes(projectDir, framework, verbose, selection);
|
|
186
|
+
if (selection.zustand) {
|
|
200
187
|
message("Zustand configured");
|
|
201
188
|
}
|
|
202
|
-
if (
|
|
189
|
+
if (selection.forms) {
|
|
203
190
|
message("React Hook Form + Zod configured");
|
|
204
191
|
}
|
|
205
|
-
if (
|
|
192
|
+
if (selection["tanstack-query"]) {
|
|
206
193
|
message("TanStack Query configured");
|
|
207
194
|
}
|
|
208
|
-
if (
|
|
195
|
+
if (selection.tailwind) {
|
|
209
196
|
message("Tailwind configured");
|
|
210
197
|
}
|
|
211
|
-
if (
|
|
198
|
+
if (selection.biome) {
|
|
212
199
|
message("Biome configured");
|
|
213
200
|
}
|
|
214
|
-
if (
|
|
201
|
+
if (selection.testing) {
|
|
215
202
|
message("Testing configured");
|
|
216
203
|
}
|
|
217
204
|
return "Dependencies installed";
|
|
@@ -222,7 +209,7 @@ export async function run(options = {}) {
|
|
|
222
209
|
task: async () => {
|
|
223
210
|
failedStep = "Initializing Git";
|
|
224
211
|
await initRepository(projectDir, verbose);
|
|
225
|
-
if (
|
|
212
|
+
if (selection.husky) {
|
|
226
213
|
await exec("pnpm", ["exec", "husky"], {
|
|
227
214
|
cwd: projectDir,
|
|
228
215
|
verbose,
|
package/dist/config/agents.js
CHANGED
package/dist/config/tech.js
CHANGED
|
@@ -4,7 +4,6 @@ export const TECH_IDS = [
|
|
|
4
4
|
"tanstack-query",
|
|
5
5
|
"zustand",
|
|
6
6
|
"forms",
|
|
7
|
-
"registry",
|
|
8
7
|
"biome",
|
|
9
8
|
"testing",
|
|
10
9
|
"husky",
|
|
@@ -28,11 +27,6 @@ export const TECH_OPTIONS = [
|
|
|
28
27
|
label: "React Hook Form + Zod",
|
|
29
28
|
hint: "Formularios con validación",
|
|
30
29
|
},
|
|
31
|
-
{
|
|
32
|
-
id: "registry",
|
|
33
|
-
label: "Registro @raulmoracode",
|
|
34
|
-
hint: ".npmrc + @raulmoracode/icons",
|
|
35
|
-
},
|
|
36
30
|
{
|
|
37
31
|
id: "biome",
|
|
38
32
|
label: "Biome",
|
|
@@ -60,7 +54,6 @@ export const FULL_TECH_SELECTION = {
|
|
|
60
54
|
"tanstack-query": true,
|
|
61
55
|
zustand: true,
|
|
62
56
|
forms: true,
|
|
63
|
-
registry: true,
|
|
64
57
|
biome: true,
|
|
65
58
|
testing: true,
|
|
66
59
|
husky: true,
|
|
@@ -75,9 +68,3 @@ export function resolveTechSelection(input) {
|
|
|
75
68
|
}
|
|
76
69
|
return { selection, notes };
|
|
77
70
|
}
|
|
78
|
-
export function applyPrivateAccess(selection, hasPrivateAccess) {
|
|
79
|
-
if (hasPrivateAccess) {
|
|
80
|
-
return selection;
|
|
81
|
-
}
|
|
82
|
-
return { ...selection, registry: false };
|
|
83
|
-
}
|
|
@@ -19,9 +19,6 @@ export function runtimeDependencies(selection = FULL_TECH_SELECTION) {
|
|
|
19
19
|
if (selection["tanstack-query"]) {
|
|
20
20
|
dependencies["@tanstack/react-query"] = "5.104.0";
|
|
21
21
|
}
|
|
22
|
-
if (selection.registry) {
|
|
23
|
-
dependencies["@raulmoracode/icons"] = "1.1.0";
|
|
24
|
-
}
|
|
25
22
|
return dependencies;
|
|
26
23
|
}
|
|
27
24
|
export function devDependencies(framework, selection = FULL_TECH_SELECTION) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raulmoracode/create",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Professional CLI to scaffold React + Vite and Next.js projects with Tailwind CSS, shadcn, Biome
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Professional CLI to scaffold React + Vite and Next.js projects with Tailwind CSS, shadcn, Biome and Vitest.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"raulmoracode",
|
|
7
7
|
"scaffold",
|
package/dist/config/npmrc.js
DELETED
package/dist/utils/registry.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const PRIVATE_ICONS_METADATA_URL = "https://npm.pkg.github.com/@raulmoracode%2Ficons";
|
|
2
|
-
const REQUEST_TIMEOUT_MS = 10_000;
|
|
3
|
-
export async function checkPrivateRegistryAccess() {
|
|
4
|
-
const token = process.env.GH_TOKEN;
|
|
5
|
-
if (!token) {
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
|
-
try {
|
|
9
|
-
const response = await fetch(PRIVATE_ICONS_METADATA_URL, {
|
|
10
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
11
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
12
|
-
});
|
|
13
|
-
return response.ok;
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|