@raulmoracode/create 1.0.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/LICENSE +21 -0
- package/README.md +231 -0
- package/dist/cli/args.js +34 -0
- package/dist/cli/output.js +20 -0
- package/dist/cli/run.js +326 -0
- package/dist/config/agents.js +224 -0
- package/dist/config/biome.js +30 -0
- package/dist/config/branding.js +2 -0
- package/dist/config/commitlint.js +8 -0
- package/dist/config/components.js +36 -0
- package/dist/config/editorconfig.js +14 -0
- package/dist/config/husky.js +14 -0
- package/dist/config/npmrc.js +3 -0
- package/dist/config/nvmrc.js +4 -0
- package/dist/config/pnpm-workspace.js +85 -0
- package/dist/config/query.js +16 -0
- package/dist/config/tailwind.js +31 -0
- package/dist/config/tech.js +83 -0
- package/dist/config/testing.js +26 -0
- package/dist/config/vscode.js +39 -0
- package/dist/frameworks/index.js +9 -0
- package/dist/frameworks/next.js +115 -0
- package/dist/frameworks/types.js +1 -0
- package/dist/frameworks/vite.js +135 -0
- package/dist/generators/configure-biome.js +22 -0
- package/dist/generators/configure-git-hooks.js +11 -0
- package/dist/generators/configure-node.js +45 -0
- package/dist/generators/configure-project.js +233 -0
- package/dist/generators/configure-registry.js +5 -0
- package/dist/generators/configure-shadcn.js +6 -0
- package/dist/generators/configure-testing.js +6 -0
- package/dist/generators/configure-vscode.js +6 -0
- package/dist/generators/create-project.js +3 -0
- package/dist/git/commit.js +12 -0
- package/dist/git/init.js +11 -0
- package/dist/git/push.js +59 -0
- package/dist/git/remote.js +30 -0
- package/dist/index.js +16 -0
- package/dist/prompts/cancel.js +8 -0
- package/dist/prompts/confirm.js +11 -0
- package/dist/prompts/framework.js +25 -0
- package/dist/prompts/github.js +25 -0
- package/dist/prompts/project.js +22 -0
- package/dist/prompts/tech.js +18 -0
- package/dist/utils/exec.js +107 -0
- package/dist/utils/filesystem.js +108 -0
- package/dist/utils/registry.js +18 -0
- package/dist/utils/validation.js +153 -0
- package/package.json +68 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
export function agentsMd() {
|
|
2
|
+
return [
|
|
3
|
+
"# AGENTS.md",
|
|
4
|
+
"",
|
|
5
|
+
"## Project guidelines",
|
|
6
|
+
"",
|
|
7
|
+
"This project was initially generated with `@raulmoracode/create`.",
|
|
8
|
+
"",
|
|
9
|
+
"Treat the current repository state as the source of truth. Do not assume that the original scaffold configuration, dependencies, scripts, or architecture are still unchanged.",
|
|
10
|
+
"",
|
|
11
|
+
"Before making changes, inspect the existing codebase and its configuration.",
|
|
12
|
+
"",
|
|
13
|
+
"## General principles",
|
|
14
|
+
"",
|
|
15
|
+
"- Follow existing project conventions and patterns.",
|
|
16
|
+
"- Prefer simple, focused solutions over unnecessary abstractions.",
|
|
17
|
+
"- Reuse existing components, utilities, hooks, and patterns when appropriate.",
|
|
18
|
+
"- Avoid duplicating functionality that already exists.",
|
|
19
|
+
"- Keep changes scoped to the requested task.",
|
|
20
|
+
"- Do not modify unrelated files.",
|
|
21
|
+
"- Preserve existing user changes.",
|
|
22
|
+
"- Do not introduce a new library when the existing project can reasonably solve the problem.",
|
|
23
|
+
"- Do not remove or replace existing dependencies without a clear reason.",
|
|
24
|
+
"- Do not reintroduce dependencies that have been intentionally removed.",
|
|
25
|
+
"",
|
|
26
|
+
"## Dependencies and configuration",
|
|
27
|
+
"",
|
|
28
|
+
"Always inspect the current `package.json` before using or adding a dependency.",
|
|
29
|
+
"",
|
|
30
|
+
"Do not assume that a dependency is installed because it may have been included in the original scaffold.",
|
|
31
|
+
"",
|
|
32
|
+
"Treat the following files as sources of truth for the current project configuration:",
|
|
33
|
+
"",
|
|
34
|
+
"- `package.json`",
|
|
35
|
+
"- `pnpm-lock.yaml`",
|
|
36
|
+
"- `tsconfig.json`",
|
|
37
|
+
"- `biome.json`",
|
|
38
|
+
"- `components.json`",
|
|
39
|
+
"- `.nvmrc`",
|
|
40
|
+
"- `.npmrc`",
|
|
41
|
+
"- framework-specific configuration files",
|
|
42
|
+
"",
|
|
43
|
+
"Use the package manager already configured by the project.",
|
|
44
|
+
"",
|
|
45
|
+
"Do not change package managers unless explicitly requested.",
|
|
46
|
+
"",
|
|
47
|
+
"## Project tooling",
|
|
48
|
+
"",
|
|
49
|
+
"This project uses pnpm exclusively. Never use npm or yarn.",
|
|
50
|
+
"",
|
|
51
|
+
"Available scripts (see `package.json` for the full list):",
|
|
52
|
+
"",
|
|
53
|
+
"- `pnpm dev` — start the development server.",
|
|
54
|
+
"- `pnpm build` — create a production build.",
|
|
55
|
+
"- `pnpm test` — run the test suite.",
|
|
56
|
+
"- `pnpm check` — run the formatter and linter check.",
|
|
57
|
+
"- `pnpm format` — apply formatting.",
|
|
58
|
+
"- `pnpm lint` — run the linter.",
|
|
59
|
+
"",
|
|
60
|
+
"UI components come from shadcn. Add new components with:",
|
|
61
|
+
"",
|
|
62
|
+
"```bash",
|
|
63
|
+
"pnpm dlx shadcn@latest add <component>",
|
|
64
|
+
"```",
|
|
65
|
+
"",
|
|
66
|
+
"Do not hand-write component files under the shadcn UI directory. Follow `components.json`, including the `@raulmoracode` registry.",
|
|
67
|
+
"",
|
|
68
|
+
"## Code style",
|
|
69
|
+
"",
|
|
70
|
+
"Follow the existing code style and project structure.",
|
|
71
|
+
"",
|
|
72
|
+
"Use the project's configured formatter and linter.",
|
|
73
|
+
"",
|
|
74
|
+
"Do not introduce ESLint, Prettier, or another formatting/linting system when an existing project tool already provides that functionality, unless explicitly requested.",
|
|
75
|
+
"",
|
|
76
|
+
"Prefer readable and maintainable code over clever implementations.",
|
|
77
|
+
"",
|
|
78
|
+
"Avoid unnecessary comments. Add comments when they explain a non-obvious decision or constraint.",
|
|
79
|
+
"",
|
|
80
|
+
"## Components and UI",
|
|
81
|
+
"",
|
|
82
|
+
"Before creating a new component, check whether an existing component already provides the required functionality.",
|
|
83
|
+
"",
|
|
84
|
+
"Prefer composition and reuse over duplicated UI implementations.",
|
|
85
|
+
"",
|
|
86
|
+
"If the project uses shadcn, follow the existing shadcn configuration and component conventions.",
|
|
87
|
+
"",
|
|
88
|
+
"Do not manually recreate a component when an appropriate existing project component can be reused.",
|
|
89
|
+
"",
|
|
90
|
+
"## Architecture",
|
|
91
|
+
"",
|
|
92
|
+
"Follow the architecture already present in the repository.",
|
|
93
|
+
"",
|
|
94
|
+
"Do not introduce a new architectural pattern solely because it is personally preferred.",
|
|
95
|
+
"",
|
|
96
|
+
"When adding functionality:",
|
|
97
|
+
"",
|
|
98
|
+
"1. Identify the existing pattern used for similar functionality.",
|
|
99
|
+
"2. Follow that pattern when appropriate.",
|
|
100
|
+
"3. Keep the implementation close to the relevant feature.",
|
|
101
|
+
"4. Avoid creating generic abstractions before they are actually needed.",
|
|
102
|
+
"",
|
|
103
|
+
"For framework-specific behavior, follow the conventions of the framework version currently installed in the project.",
|
|
104
|
+
"",
|
|
105
|
+
"## Validation",
|
|
106
|
+
"",
|
|
107
|
+
"Inspect `package.json` to determine the available scripts before running commands.",
|
|
108
|
+
"",
|
|
109
|
+
"After making changes, run the most relevant validation commands for the affected code.",
|
|
110
|
+
"",
|
|
111
|
+
"For substantial changes, prefer running:",
|
|
112
|
+
"",
|
|
113
|
+
"```bash",
|
|
114
|
+
"pnpm check",
|
|
115
|
+
"pnpm test",
|
|
116
|
+
"pnpm build",
|
|
117
|
+
"```",
|
|
118
|
+
"",
|
|
119
|
+
"Do not claim that a change is complete if the relevant validation has not been performed.",
|
|
120
|
+
"",
|
|
121
|
+
"If a validation command fails because of an unrelated pre-existing problem, distinguish that from problems introduced by the current change.",
|
|
122
|
+
"",
|
|
123
|
+
"## Git",
|
|
124
|
+
"",
|
|
125
|
+
"Never use destructive Git commands unless explicitly requested.",
|
|
126
|
+
"",
|
|
127
|
+
"Do not use:",
|
|
128
|
+
"",
|
|
129
|
+
"```bash",
|
|
130
|
+
"git push --force",
|
|
131
|
+
"git push -f",
|
|
132
|
+
"git reset --hard",
|
|
133
|
+
"git clean -fd",
|
|
134
|
+
"```",
|
|
135
|
+
"",
|
|
136
|
+
"Do not rewrite existing history unnecessarily.",
|
|
137
|
+
"",
|
|
138
|
+
"Do not discard or overwrite uncommitted user changes.",
|
|
139
|
+
"",
|
|
140
|
+
"Before modifying files, be aware of the current Git state when relevant.",
|
|
141
|
+
"",
|
|
142
|
+
"Do not commit changes unless explicitly requested.",
|
|
143
|
+
"",
|
|
144
|
+
"## Git hooks and commits",
|
|
145
|
+
"",
|
|
146
|
+
"Husky manages the Git hooks.",
|
|
147
|
+
"",
|
|
148
|
+
"`pre-commit` runs:",
|
|
149
|
+
"",
|
|
150
|
+
"```bash",
|
|
151
|
+
"pnpm check",
|
|
152
|
+
"pnpm test",
|
|
153
|
+
"```",
|
|
154
|
+
"",
|
|
155
|
+
"`commit-msg` runs Commitlint.",
|
|
156
|
+
"",
|
|
157
|
+
"Commits must follow Conventional Commits.",
|
|
158
|
+
"",
|
|
159
|
+
"Valid commit examples:",
|
|
160
|
+
"",
|
|
161
|
+
"```text",
|
|
162
|
+
"feat: add user profile",
|
|
163
|
+
"fix: handle invalid input",
|
|
164
|
+
"refactor: extract API client",
|
|
165
|
+
"test: add query client tests",
|
|
166
|
+
"docs: update project guide",
|
|
167
|
+
"chore: update dependencies",
|
|
168
|
+
"```",
|
|
169
|
+
"",
|
|
170
|
+
"Do not bypass hooks with `--no-verify` unless explicitly requested.",
|
|
171
|
+
"",
|
|
172
|
+
"Keep the project passing:",
|
|
173
|
+
"",
|
|
174
|
+
"```bash",
|
|
175
|
+
"pnpm check",
|
|
176
|
+
"pnpm test",
|
|
177
|
+
"pnpm build",
|
|
178
|
+
"```",
|
|
179
|
+
"",
|
|
180
|
+
"## Security",
|
|
181
|
+
"",
|
|
182
|
+
"Do not expose, commit, or hard-code secrets, API keys, access tokens, passwords, or credentials.",
|
|
183
|
+
"",
|
|
184
|
+
"Never replace environment variables with hard-coded credentials.",
|
|
185
|
+
"",
|
|
186
|
+
"Treat `.env` and other environment-specific files as sensitive.",
|
|
187
|
+
"",
|
|
188
|
+
"Do not weaken existing security mechanisms merely to make a task easier.",
|
|
189
|
+
"",
|
|
190
|
+
"## Dependency changes",
|
|
191
|
+
"",
|
|
192
|
+
"Before adding a dependency:",
|
|
193
|
+
"",
|
|
194
|
+
"1. Check whether the functionality already exists in the project.",
|
|
195
|
+
"2. Check whether an existing dependency can provide it.",
|
|
196
|
+
"3. Consider whether the dependency is actually necessary.",
|
|
197
|
+
"4. Use the package manager configured by the project.",
|
|
198
|
+
"5. Keep dependency versions consistent with the project's existing conventions.",
|
|
199
|
+
"",
|
|
200
|
+
"Avoid adding dependencies for trivial functionality that can be implemented safely with the existing stack.",
|
|
201
|
+
"",
|
|
202
|
+
"## Working with existing code",
|
|
203
|
+
"",
|
|
204
|
+
"Do not rewrite working code unnecessarily.",
|
|
205
|
+
"",
|
|
206
|
+
"Prefer the smallest change that correctly solves the requested problem.",
|
|
207
|
+
"",
|
|
208
|
+
"When modifying existing functionality, preserve its current behavior unless the task explicitly requires changing it.",
|
|
209
|
+
"",
|
|
210
|
+
"If the requested change conflicts with an existing architectural decision, inspect the relevant code and configuration before deciding how to proceed.",
|
|
211
|
+
"",
|
|
212
|
+
"## Final response",
|
|
213
|
+
"",
|
|
214
|
+
"When completing a task, briefly report:",
|
|
215
|
+
"",
|
|
216
|
+
"- What was changed.",
|
|
217
|
+
"- Which files were modified.",
|
|
218
|
+
"- What validation was performed.",
|
|
219
|
+
"- Any relevant issues or limitations that remain.",
|
|
220
|
+
"",
|
|
221
|
+
"Do not claim tests, builds, or other commands were executed if they were not actually run.",
|
|
222
|
+
"",
|
|
223
|
+
].join("\n");
|
|
224
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function biomeConfig() {
|
|
2
|
+
return `${JSON.stringify({
|
|
3
|
+
$schema: "./node_modules/@biomejs/biome/configuration_schema.json",
|
|
4
|
+
files: {
|
|
5
|
+
includes: ["**", "!dist", "!.next"],
|
|
6
|
+
},
|
|
7
|
+
formatter: {
|
|
8
|
+
enabled: true,
|
|
9
|
+
indentStyle: "space",
|
|
10
|
+
indentWidth: 2,
|
|
11
|
+
},
|
|
12
|
+
assist: {
|
|
13
|
+
enabled: true,
|
|
14
|
+
actions: {
|
|
15
|
+
source: {
|
|
16
|
+
organizeImports: "on",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
linter: {
|
|
21
|
+
enabled: true,
|
|
22
|
+
rules: {
|
|
23
|
+
a11y: {
|
|
24
|
+
noSvgWithoutTitle: "off",
|
|
25
|
+
noAmbiguousAnchorText: "off",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}, null, 2)}\n`;
|
|
30
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const RAULMORACODE_REGISTRY_NAME = "@raulmoracode";
|
|
2
|
+
export const RAULMORACODE_REGISTRY_URL = "https://registry.raulmoracode.com/r/{name}.json";
|
|
3
|
+
export function componentsJson(options) {
|
|
4
|
+
return `${JSON.stringify({
|
|
5
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
6
|
+
style: "new-york",
|
|
7
|
+
rsc: options.rsc,
|
|
8
|
+
tsx: true,
|
|
9
|
+
tailwind: {
|
|
10
|
+
css: options.tailwindCssPath,
|
|
11
|
+
baseColor: "neutral",
|
|
12
|
+
cssVariables: true,
|
|
13
|
+
},
|
|
14
|
+
aliases: {
|
|
15
|
+
components: "@/components",
|
|
16
|
+
ui: "@/components/ui",
|
|
17
|
+
lib: "@/lib",
|
|
18
|
+
hooks: "@/hooks",
|
|
19
|
+
utils: "@/lib/utils",
|
|
20
|
+
},
|
|
21
|
+
registries: {
|
|
22
|
+
[RAULMORACODE_REGISTRY_NAME]: RAULMORACODE_REGISTRY_URL,
|
|
23
|
+
},
|
|
24
|
+
}, null, 2)}\n`;
|
|
25
|
+
}
|
|
26
|
+
export function utilsTs() {
|
|
27
|
+
return [
|
|
28
|
+
'import { clsx, type ClassValue } from "clsx";',
|
|
29
|
+
'import { twMerge } from "tailwind-merge";',
|
|
30
|
+
"",
|
|
31
|
+
"export function cn(...inputs: ClassValue[]) {",
|
|
32
|
+
" return twMerge(clsx(inputs));",
|
|
33
|
+
"}",
|
|
34
|
+
"",
|
|
35
|
+
].join("\n");
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function editorconfigContent() {
|
|
2
|
+
return [
|
|
3
|
+
"root = true",
|
|
4
|
+
"",
|
|
5
|
+
"[*]",
|
|
6
|
+
"charset = utf-8",
|
|
7
|
+
"end_of_line = lf",
|
|
8
|
+
"indent_style = space",
|
|
9
|
+
"indent_size = 2",
|
|
10
|
+
"insert_final_newline = true",
|
|
11
|
+
"trim_trailing_whitespace = true",
|
|
12
|
+
"",
|
|
13
|
+
].join("\n");
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FULL_TECH_SELECTION } from "./tech.js";
|
|
2
|
+
export function huskyPreCommit(selection = FULL_TECH_SELECTION) {
|
|
3
|
+
const lines = [];
|
|
4
|
+
if (selection.biome) {
|
|
5
|
+
lines.push("pnpm check");
|
|
6
|
+
}
|
|
7
|
+
if (selection.testing) {
|
|
8
|
+
lines.push("pnpm test");
|
|
9
|
+
}
|
|
10
|
+
return [...lines, ""].join("\n");
|
|
11
|
+
}
|
|
12
|
+
export function huskyCommitMsg() {
|
|
13
|
+
return ['pnpm exec commitlint --edit "$1"', ""].join("\n");
|
|
14
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const PNPM_MINIMUM_RELEASE_AGE = 10080;
|
|
2
|
+
export function pnpmWorkspaceYaml() {
|
|
3
|
+
return `minimumReleaseAge: ${PNPM_MINIMUM_RELEASE_AGE}\n`;
|
|
4
|
+
}
|
|
5
|
+
const DEPENDENCY_SECTIONS = [
|
|
6
|
+
"dependencies",
|
|
7
|
+
"devDependencies",
|
|
8
|
+
"optionalDependencies",
|
|
9
|
+
"peerDependencies",
|
|
10
|
+
];
|
|
11
|
+
export function collectLockedPackages(tree) {
|
|
12
|
+
const found = new Set();
|
|
13
|
+
const visit = (node) => {
|
|
14
|
+
if (!node || typeof node !== "object") {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const record = node;
|
|
18
|
+
for (const section of DEPENDENCY_SECTIONS) {
|
|
19
|
+
const deps = record[section];
|
|
20
|
+
if (!deps || typeof deps !== "object") {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
for (const [name, child] of Object.entries(deps)) {
|
|
24
|
+
if (!child || typeof child !== "object") {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const version = child.version;
|
|
28
|
+
if (typeof version === "string" && version.length > 0) {
|
|
29
|
+
found.add(`${name}@${version}`);
|
|
30
|
+
}
|
|
31
|
+
visit(child);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
if (Array.isArray(tree)) {
|
|
36
|
+
for (const project of tree) {
|
|
37
|
+
visit(project);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
visit(tree);
|
|
42
|
+
}
|
|
43
|
+
return [...found].sort();
|
|
44
|
+
}
|
|
45
|
+
export function mergePnpmWorkspaceYaml(existing, excludePackages = []) {
|
|
46
|
+
const releaseLine = `minimumReleaseAge: ${PNPM_MINIMUM_RELEASE_AGE}`;
|
|
47
|
+
const base = !existing || existing.trim() === "" ? "" : existing;
|
|
48
|
+
const lines = base === "" ? [] : base.split("\n");
|
|
49
|
+
while (lines.length > 0 && (lines[lines.length - 1]?.trim() ?? "") === "") {
|
|
50
|
+
lines.pop();
|
|
51
|
+
}
|
|
52
|
+
const preserved = [];
|
|
53
|
+
const existingExcludes = [];
|
|
54
|
+
let inExcludeBlock = false;
|
|
55
|
+
for (const line of lines) {
|
|
56
|
+
if (/^minimumReleaseAge\s*:/.test(line)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (/^minimumReleaseAgeExclude\s*:/.test(line)) {
|
|
60
|
+
inExcludeBlock = true;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (inExcludeBlock) {
|
|
64
|
+
const item = /^\s*-\s*(.+?)\s*$/.exec(line);
|
|
65
|
+
if (item?.[1]) {
|
|
66
|
+
existingExcludes.push(item[1]);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (line.trim() === "") {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
inExcludeBlock = false;
|
|
73
|
+
}
|
|
74
|
+
preserved.push(line);
|
|
75
|
+
}
|
|
76
|
+
const excludes = [...new Set([...existingExcludes, ...excludePackages])];
|
|
77
|
+
const out = [releaseLine, ...preserved];
|
|
78
|
+
if (excludes.length > 0) {
|
|
79
|
+
out.push("minimumReleaseAgeExclude:");
|
|
80
|
+
for (const pkg of excludes) {
|
|
81
|
+
out.push(` - '${pkg}'`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return `${out.join("\n")}\n`;
|
|
85
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function queryClientConfig() {
|
|
2
|
+
return [
|
|
3
|
+
'import { QueryClient } from "@tanstack/react-query";',
|
|
4
|
+
"",
|
|
5
|
+
"export const queryClient = new QueryClient({",
|
|
6
|
+
" defaultOptions: {",
|
|
7
|
+
" queries: {",
|
|
8
|
+
" staleTime: 60 * 1000,",
|
|
9
|
+
" gcTime: 5 * 60 * 1000,",
|
|
10
|
+
" retry: false,",
|
|
11
|
+
" },",
|
|
12
|
+
" },",
|
|
13
|
+
"});",
|
|
14
|
+
"",
|
|
15
|
+
].join("\n");
|
|
16
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function tailwindCss() {
|
|
2
|
+
return '@import "tailwindcss";\n';
|
|
3
|
+
}
|
|
4
|
+
export function viteTailwindConfig() {
|
|
5
|
+
return [
|
|
6
|
+
'import { fileURLToPath, URL } from "node:url";',
|
|
7
|
+
'import { defineConfig } from "vite";',
|
|
8
|
+
'import react from "@vitejs/plugin-react";',
|
|
9
|
+
'import tailwindcss from "@tailwindcss/vite";',
|
|
10
|
+
"",
|
|
11
|
+
"export default defineConfig({",
|
|
12
|
+
" plugins: [react(), tailwindcss()],",
|
|
13
|
+
" resolve: {",
|
|
14
|
+
" alias: {",
|
|
15
|
+
' "@": fileURLToPath(new URL("./src", import.meta.url)),',
|
|
16
|
+
" },",
|
|
17
|
+
" },",
|
|
18
|
+
"});",
|
|
19
|
+
"",
|
|
20
|
+
].join("\n");
|
|
21
|
+
}
|
|
22
|
+
export function nextPostcssConfig() {
|
|
23
|
+
return [
|
|
24
|
+
"const config = {",
|
|
25
|
+
' plugins: ["@tailwindcss/postcss"],',
|
|
26
|
+
"};",
|
|
27
|
+
"",
|
|
28
|
+
"export default config;",
|
|
29
|
+
"",
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export const TECH_IDS = [
|
|
2
|
+
"tailwind",
|
|
3
|
+
"shadcn",
|
|
4
|
+
"tanstack-query",
|
|
5
|
+
"zustand",
|
|
6
|
+
"forms",
|
|
7
|
+
"registry",
|
|
8
|
+
"biome",
|
|
9
|
+
"testing",
|
|
10
|
+
"husky",
|
|
11
|
+
"vscode",
|
|
12
|
+
];
|
|
13
|
+
export const TECH_OPTIONS = [
|
|
14
|
+
{ id: "tailwind", label: "Tailwind CSS", hint: "Estilos con Tailwind 4" },
|
|
15
|
+
{
|
|
16
|
+
id: "shadcn",
|
|
17
|
+
label: "shadcn",
|
|
18
|
+
hint: "components.json + cn() (requiere Tailwind)",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "tanstack-query",
|
|
22
|
+
label: "TanStack Query",
|
|
23
|
+
hint: "QueryClient + provider",
|
|
24
|
+
},
|
|
25
|
+
{ id: "zustand", label: "Zustand", hint: "Estado global" },
|
|
26
|
+
{
|
|
27
|
+
id: "forms",
|
|
28
|
+
label: "React Hook Form + Zod",
|
|
29
|
+
hint: "Formularios con validación",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "registry",
|
|
33
|
+
label: "Registro @raulmoracode",
|
|
34
|
+
hint: ".npmrc + @raulmoracode/icons",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "biome",
|
|
38
|
+
label: "Biome",
|
|
39
|
+
hint: "Formato, lint y scripts check/format/lint",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "testing",
|
|
43
|
+
label: "Testing",
|
|
44
|
+
hint: "Vitest + Testing Library y script test",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "husky",
|
|
48
|
+
label: "Husky + Commitlint",
|
|
49
|
+
hint: "Git hooks y Conventional Commits",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "vscode",
|
|
53
|
+
label: "VS Code",
|
|
54
|
+
hint: ".vscode/settings.json + extensions.json",
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
export const FULL_TECH_SELECTION = {
|
|
58
|
+
tailwind: true,
|
|
59
|
+
shadcn: true,
|
|
60
|
+
"tanstack-query": true,
|
|
61
|
+
zustand: true,
|
|
62
|
+
forms: true,
|
|
63
|
+
registry: true,
|
|
64
|
+
biome: true,
|
|
65
|
+
testing: true,
|
|
66
|
+
husky: true,
|
|
67
|
+
vscode: true,
|
|
68
|
+
};
|
|
69
|
+
export function resolveTechSelection(input) {
|
|
70
|
+
const selection = { ...input };
|
|
71
|
+
const notes = [];
|
|
72
|
+
if (selection.shadcn && !selection.tailwind) {
|
|
73
|
+
selection.tailwind = true;
|
|
74
|
+
notes.push("shadcn necesita Tailwind CSS: se mantiene Tailwind.");
|
|
75
|
+
}
|
|
76
|
+
return { selection, notes };
|
|
77
|
+
}
|
|
78
|
+
export function applyPrivateAccess(selection, hasPrivateAccess) {
|
|
79
|
+
if (hasPrivateAccess) {
|
|
80
|
+
return selection;
|
|
81
|
+
}
|
|
82
|
+
return { ...selection, registry: false };
|
|
83
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function vitestConfig() {
|
|
2
|
+
return [
|
|
3
|
+
'import { defineConfig } from "vitest/config";',
|
|
4
|
+
"",
|
|
5
|
+
"export default defineConfig({",
|
|
6
|
+
" test: {",
|
|
7
|
+
' environment: "jsdom",',
|
|
8
|
+
" },",
|
|
9
|
+
"});",
|
|
10
|
+
"",
|
|
11
|
+
].join("\n");
|
|
12
|
+
}
|
|
13
|
+
export function smokeTest() {
|
|
14
|
+
return [
|
|
15
|
+
'import { render, screen } from "@testing-library/react";',
|
|
16
|
+
'import { describe, expect, it } from "vitest";',
|
|
17
|
+
"",
|
|
18
|
+
'describe("testing setup", () => {',
|
|
19
|
+
' it("renders with the jsdom environment", () => {',
|
|
20
|
+
" render(<h1>raulmoracode</h1>);",
|
|
21
|
+
' expect(screen.getByRole("heading", { name: "raulmoracode" })).toBeDefined();',
|
|
22
|
+
" });",
|
|
23
|
+
"});",
|
|
24
|
+
"",
|
|
25
|
+
].join("\n");
|
|
26
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function vscodeSettings() {
|
|
2
|
+
return `${JSON.stringify({
|
|
3
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
4
|
+
"editor.formatOnSave": true,
|
|
5
|
+
"editor.codeActionsOnSave": {
|
|
6
|
+
"quickfix.biome": "explicit",
|
|
7
|
+
"source.organizeImports.biome": "explicit",
|
|
8
|
+
},
|
|
9
|
+
"[javascript]": {
|
|
10
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
11
|
+
},
|
|
12
|
+
"[javascriptreact]": {
|
|
13
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
14
|
+
},
|
|
15
|
+
"[typescript]": {
|
|
16
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
17
|
+
},
|
|
18
|
+
"[typescriptreact]": {
|
|
19
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
20
|
+
},
|
|
21
|
+
"[json]": {
|
|
22
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
23
|
+
},
|
|
24
|
+
"[jsonc]": {
|
|
25
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
26
|
+
},
|
|
27
|
+
"editor.insertSpaces": true,
|
|
28
|
+
"editor.tabSize": 2,
|
|
29
|
+
"editor.detectIndentation": false,
|
|
30
|
+
"files.trimTrailingWhitespace": true,
|
|
31
|
+
"files.insertFinalNewline": true,
|
|
32
|
+
"js/ts.tsdk.path": "node_modules/typescript/lib",
|
|
33
|
+
}, null, 2)}\n`;
|
|
34
|
+
}
|
|
35
|
+
export function vscodeExtensions() {
|
|
36
|
+
return `${JSON.stringify({
|
|
37
|
+
recommendations: ["biomejs.biome"],
|
|
38
|
+
}, null, 2)}\n`;
|
|
39
|
+
}
|