create-rv 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 +146 -0
- package/dist/cli.js +62 -0
- package/dist/cli.js.map +1 -0
- package/dist/copyDotfiles.js +30 -0
- package/dist/copyDotfiles.js.map +1 -0
- package/dist/git.js +14 -0
- package/dist/git.js.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/installers/eslint.js +17 -0
- package/dist/installers/eslint.js.map +1 -0
- package/dist/installers/index.js +46 -0
- package/dist/installers/index.js.map +1 -0
- package/dist/installers/prettier.js +11 -0
- package/dist/installers/prettier.js.map +1 -0
- package/dist/installers/query.js +8 -0
- package/dist/installers/query.js.map +1 -0
- package/dist/installers/rhf.js +9 -0
- package/dist/installers/rhf.js.map +1 -0
- package/dist/installers/router-react-router.js +6 -0
- package/dist/installers/router-react-router.js.map +1 -0
- package/dist/installers/router-tanstack.js +7 -0
- package/dist/installers/router-tanstack.js.map +1 -0
- package/dist/installers/router.js +10 -0
- package/dist/installers/router.js.map +1 -0
- package/dist/installers/shadcn.js +25 -0
- package/dist/installers/shadcn.js.map +1 -0
- package/dist/installers/zod.js +8 -0
- package/dist/installers/zod.js.map +1 -0
- package/dist/installers/zustand.js +8 -0
- package/dist/installers/zustand.js.map +1 -0
- package/dist/log.js +25 -0
- package/dist/log.js.map +1 -0
- package/dist/options.js +28 -0
- package/dist/options.js.map +1 -0
- package/dist/pkgManager.js +34 -0
- package/dist/pkgManager.js.map +1 -0
- package/dist/prompts.js +85 -0
- package/dist/prompts.js.map +1 -0
- package/dist/scaffold.js +211 -0
- package/dist/scaffold.js.map +1 -0
- package/package.json +55 -0
- package/templates/base/README.md +60 -0
- package/templates/base/js/index.html +13 -0
- package/templates/base/js/jsconfig.json +16 -0
- package/templates/base/js/package.json +22 -0
- package/templates/base/js/src/App.jsx +10 -0
- package/templates/base/js/src/index.css +6 -0
- package/templates/base/js/src/main.jsx +10 -0
- package/templates/base/js/vite.config.js +13 -0
- package/templates/base/ts/index.html +13 -0
- package/templates/base/ts/package.json +26 -0
- package/templates/base/ts/src/App.tsx +10 -0
- package/templates/base/ts/src/index.css +6 -0
- package/templates/base/ts/src/main.tsx +10 -0
- package/templates/base/ts/src/vite-env.d.ts +1 -0
- package/templates/base/ts/tsconfig.json +27 -0
- package/templates/base/ts/tsconfig.node.json +12 -0
- package/templates/base/ts/vite.config.ts +13 -0
- package/templates/extras/eslint/.eslintignore +3 -0
- package/templates/extras/eslint/eslint.config.js +37 -0
- package/templates/extras/prettier/.prettierignore +7 -0
- package/templates/extras/prettier/.prettierrc +8 -0
- package/templates/extras/query/src/main.tsx +15 -0
- package/templates/extras/rhf/src/components/ExampleForm.tsx +40 -0
- package/templates/extras/router-react-router/src/App.tsx +24 -0
- package/templates/extras/router-react-router/src/main.tsx +13 -0
- package/templates/extras/router-react-router/src/pages/about.tsx +7 -0
- package/templates/extras/router-react-router/src/pages/home.tsx +7 -0
- package/templates/extras/router-tanstack/src/main.tsx +19 -0
- package/templates/extras/router-tanstack/src/routes/__root.tsx +16 -0
- package/templates/extras/router-tanstack/src/routes/about.tsx +13 -0
- package/templates/extras/router-tanstack/src/routes/index.tsx +13 -0
- package/templates/extras/router-tanstack/vite.config.ts +18 -0
- package/templates/extras/shadcn/components.json +19 -0
- package/templates/extras/shadcn/src/components/ui/button.tsx +45 -0
- package/templates/extras/shadcn/src/components/ui/card.tsx +34 -0
- package/templates/extras/shadcn/src/components/ui/input.tsx +19 -0
- package/templates/extras/shadcn/src/index.css +85 -0
- package/templates/extras/shadcn/src/lib/utils.ts +6 -0
- package/templates/extras/zod/src/lib/schemas.ts +8 -0
- package/templates/extras/zustand/src/lib/store.ts +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# create-rv
|
|
2
|
+
|
|
3
|
+
A zero-config CLI that scaffolds a **Vite + React 19 + Tailwind v4** app with the
|
|
4
|
+
`rollout` stack pre-wired: router, state, data, forms, validation, shadcn/ui,
|
|
5
|
+
lint, and format. Choose **TypeScript or JavaScript** and one of three routers
|
|
6
|
+
interactively, or skip the prompts with flags.
|
|
7
|
+
|
|
8
|
+
## what you get
|
|
9
|
+
|
|
10
|
+
- **Vite** + **React 19** + **TypeScript** (or JavaScript) with `@/*` path alias
|
|
11
|
+
- **Tailwind v4** wired via `@tailwindcss/vite` — no `tailwind.config.js`,
|
|
12
|
+
no `postcss.config.js`, just `@import "tailwindcss"` in `src/index.css`
|
|
13
|
+
- **Router** — pick one:
|
|
14
|
+
- `tanstack` — TanStack Router (file-based, type-safe, vite plugin, generates `routeTree.gen.ts`)
|
|
15
|
+
- `react-router` — React Router v8 (declarative: `BrowserRouter` + `Link`/`Route`/`Routes` imported from `react-router`)
|
|
16
|
+
- `none` — single-page shell
|
|
17
|
+
- **shadcn/ui** (primed) — `components.json`, `cn()` util, `Button`/`Card`/`Input` components, oklch theme tokens, `tsx` flag in `components.json` flips with language
|
|
18
|
+
- **TanStack Query** — `QueryClientProvider` wired for the chosen router
|
|
19
|
+
- **Zustand** — sample store at `src/lib/store.ts`
|
|
20
|
+
- **React Hook Form + Zod** — example form at `src/components/ExampleForm.tsx`
|
|
21
|
+
- **ESLint** — flat config, Vercel/TS style + import sort + tailwind
|
|
22
|
+
- **Prettier** — with `prettier-plugin-tailwindcss`
|
|
23
|
+
- **4 package managers** — `npm`, `pnpm`, `yarn`, `bun`
|
|
24
|
+
- **Optional** `git init` and dependency install
|
|
25
|
+
|
|
26
|
+
## usage
|
|
27
|
+
|
|
28
|
+
### interactive
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx create-rv my-app
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
You'll be prompted for project name, package manager, language, router, and
|
|
35
|
+
extras. Press Enter at the router prompt to accept the default
|
|
36
|
+
(**React Router v8**).
|
|
37
|
+
|
|
38
|
+
### non-interactive (CI / scripts)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx create-rv my-app \
|
|
42
|
+
--pkg pnpm \
|
|
43
|
+
--lang ts \
|
|
44
|
+
--router react-router \
|
|
45
|
+
--with query,zustand,rhf,zod,eslint,prettier,shadcn \
|
|
46
|
+
--install \
|
|
47
|
+
--yes
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`--yes` accepts all defaults and skips prompts.
|
|
51
|
+
|
|
52
|
+
## flags
|
|
53
|
+
|
|
54
|
+
| flag | values | default |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| `--pkg` | `npm` \| `pnpm` \| `yarn` \| `bun` | `npm` |
|
|
57
|
+
| `--lang` | `ts` \| `js` | `ts` |
|
|
58
|
+
| `--router` | `tanstack` \| `react-router` \| `none` | `react-router` |
|
|
59
|
+
| `--with` | comma-separated extras | all extras |
|
|
60
|
+
| `--no-git` | skip `git init` | git inits by default |
|
|
61
|
+
| `--install` | run install after scaffold | off |
|
|
62
|
+
| `-y`, `--yes` | accept all defaults, no prompts | off |
|
|
63
|
+
|
|
64
|
+
Available extras: `query`, `zustand`, `rhf`, `zod`, `eslint`, `prettier`, `shadcn`.
|
|
65
|
+
|
|
66
|
+
## after scaffold
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
cd my-app
|
|
70
|
+
pnpm dev
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add more shadcn components:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pnpm dlx shadcn@latest add dialog
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Lint and format (if included):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pnpm lint
|
|
83
|
+
pnpm format
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## how it works
|
|
87
|
+
|
|
88
|
+
1. **Parse** CLI args via `commander`.
|
|
89
|
+
2. **Prompt** for any missing values via `@clack/prompts` (skipped if every
|
|
90
|
+
choice was provided as a flag or `--yes` is set).
|
|
91
|
+
3. **Copy** `templates/base/<lang>/` (Vite + React skeleton) into the
|
|
92
|
+
destination, then dotfiles from `templates/base/`.
|
|
93
|
+
4. **Overlay** the chosen router from `templates/extras/router-*/` and
|
|
94
|
+
**install** its package via `src/installers/router-*.ts`.
|
|
95
|
+
5. **Install** each selected extra by copying its template overlay and adding
|
|
96
|
+
deps + scripts to `package.json`.
|
|
97
|
+
6. **Rewrite** to JS if `--lang js`: rename `.ts`→`.js`, `.tsx`→`.jsx`, drop
|
|
98
|
+
`.d.ts` and `typescript` deps, strip `tsc` from `build`.
|
|
99
|
+
7. **Optionally** `git init` and run install.
|
|
100
|
+
8. **Render** the generated project's `README.md` from a `__STACK_LIST__` /
|
|
101
|
+
`__SCRIPTS_EXTRA__` template.
|
|
102
|
+
|
|
103
|
+
Templates live in `templates/base/{ts,js}/` and `templates/extras/*/`. Each
|
|
104
|
+
extra has an installer in `src/installers/` that copies its overlay and mutates
|
|
105
|
+
`package.json`.
|
|
106
|
+
|
|
107
|
+
## router notes
|
|
108
|
+
|
|
109
|
+
- **TanStack Router** is file-based. Routes live in `src/routes/`; the vite
|
|
110
|
+
plugin generates `routeTree.gen.ts` on dev/build. `<RouterProvider>` wraps
|
|
111
|
+
the app in `main.tsx`.
|
|
112
|
+
- **React Router v8** uses the declarative API: `BrowserRouter` wraps `<App />`
|
|
113
|
+
in `main.tsx`, and `App.tsx` uses `<Routes>` / `<Route>` / `<Link>`.
|
|
114
|
+
Everything is imported from `react-router` (in v8 the declarative API is in
|
|
115
|
+
the root package; `react-router-dom` is removed).
|
|
116
|
+
|
|
117
|
+
## project layout
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
src/
|
|
121
|
+
cli.ts # commander setup + flag parsing
|
|
122
|
+
prompts.ts # clack interactive prompts
|
|
123
|
+
scaffold.ts # main scaffold orchestration
|
|
124
|
+
options.ts # types + valid value lists
|
|
125
|
+
copyDotfiles.ts # walker that copies dotfiles (cpSync skips them on node 25)
|
|
126
|
+
installers/ # one file per extra; mutates pkg + copies overlay
|
|
127
|
+
templates/
|
|
128
|
+
base/{ts,js}/ # Vite+React skeleton
|
|
129
|
+
extras/<name>/ # overlay files copied into the project
|
|
130
|
+
scripts/
|
|
131
|
+
smoke.mjs # scaffolds 4 variants into /tmp and asserts files
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## dev
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pnpm install
|
|
138
|
+
pnpm build # tsc -> dist/
|
|
139
|
+
node dist/index.js /tmp/demo --pkg npm --with shadcn --no-git --yes
|
|
140
|
+
node scripts/smoke.mjs # scaffolds 4 variants, asserts files
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Smoke covers 4 variants: `ts × tanstack`, `js × tanstack`,
|
|
144
|
+
`ts × react-router + shadcn`, `js × react-router + shadcn`, plus a
|
|
145
|
+
regression check that react-router `main.tsx` wraps `<App />` in
|
|
146
|
+
`<BrowserRouter>` imported from `react-router`.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { ALL_EXTRAS, LANG_CHOICES, ROUTER_CHOICES, isExtraKey, isLang, isRouterChoice, VALID_PKG, } from "./options.js";
|
|
3
|
+
export function buildProgram() {
|
|
4
|
+
const program = new Command();
|
|
5
|
+
program
|
|
6
|
+
.name("create-rv")
|
|
7
|
+
.description("Scaffold a Vite+React+TS app with the rollout stack.")
|
|
8
|
+
.version("0.1.0")
|
|
9
|
+
.argument("[project-name]", "name of the project directory")
|
|
10
|
+
.option("--pkg <pm>", `package manager: ${VALID_PKG.join("|")}`)
|
|
11
|
+
.option("--router <choice>", `router: ${ROUTER_CHOICES.join("|")} (default: react-router)`)
|
|
12
|
+
.option("--lang <choice>", `language: ${LANG_CHOICES.join("|")} (default: ts)`)
|
|
13
|
+
.option("--with <list>", `comma-separated extras. available: ${ALL_EXTRAS.join(",")}`)
|
|
14
|
+
.option("--no-git", "skip git init")
|
|
15
|
+
.option("--install", "run install after scaffold", false)
|
|
16
|
+
.option("-y, --yes", "accept defaults, no prompts", false)
|
|
17
|
+
.allowExcessArguments(false);
|
|
18
|
+
return program;
|
|
19
|
+
}
|
|
20
|
+
export function parseCli(argv) {
|
|
21
|
+
const program = buildProgram();
|
|
22
|
+
const out = {
|
|
23
|
+
extras: [],
|
|
24
|
+
git: true,
|
|
25
|
+
install: false,
|
|
26
|
+
yes: false,
|
|
27
|
+
};
|
|
28
|
+
program.parse(argv);
|
|
29
|
+
const projectName = program.args[0];
|
|
30
|
+
if (typeof projectName === "string")
|
|
31
|
+
out.projectName = projectName;
|
|
32
|
+
const opts = program.opts();
|
|
33
|
+
if (opts.pkg) {
|
|
34
|
+
if (!VALID_PKG.includes(opts.pkg)) {
|
|
35
|
+
throw new Error(`invalid --pkg, must be one of ${VALID_PKG.join("|")}`);
|
|
36
|
+
}
|
|
37
|
+
out.pkgManager = opts.pkg;
|
|
38
|
+
}
|
|
39
|
+
if (opts.router) {
|
|
40
|
+
if (!isRouterChoice(opts.router)) {
|
|
41
|
+
throw new Error(`invalid --router, must be one of ${ROUTER_CHOICES.join("|")}`);
|
|
42
|
+
}
|
|
43
|
+
out.router = opts.router;
|
|
44
|
+
}
|
|
45
|
+
if (opts.lang) {
|
|
46
|
+
if (!isLang(opts.lang)) {
|
|
47
|
+
throw new Error(`invalid --lang, must be one of ${LANG_CHOICES.join("|")}`);
|
|
48
|
+
}
|
|
49
|
+
out.lang = opts.lang;
|
|
50
|
+
}
|
|
51
|
+
if (opts.with) {
|
|
52
|
+
out.extras = opts.with
|
|
53
|
+
.split(",")
|
|
54
|
+
.map((s) => s.trim())
|
|
55
|
+
.filter((s) => isExtraKey(s));
|
|
56
|
+
}
|
|
57
|
+
out.git = opts.git !== false;
|
|
58
|
+
out.install = opts.install === true;
|
|
59
|
+
out.yes = opts.yes === true;
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively copy dotfiles (e.g. `.gitignore`, `.prettierrc`, `.eslintignore`)
|
|
5
|
+
* from `srcRoot` to `destRoot`, preserving relative paths. node 25's cpSync
|
|
6
|
+
* silently skips dotfiles, so we walk manually. Overwrites by default.
|
|
7
|
+
*/
|
|
8
|
+
export function copyDotfiles(srcRoot, destRoot, overwrite = true) {
|
|
9
|
+
if (!existsSync(srcRoot))
|
|
10
|
+
return;
|
|
11
|
+
const entries = readdirSync(srcRoot, { withFileTypes: true });
|
|
12
|
+
for (const e of entries) {
|
|
13
|
+
if (e.name === "node_modules" || e.name === ".git" || e.name === "dist")
|
|
14
|
+
continue;
|
|
15
|
+
const srcPath = join(srcRoot, e.name);
|
|
16
|
+
if (e.isDirectory()) {
|
|
17
|
+
copyDotfiles(srcPath, destRoot, overwrite);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (!e.name.startsWith("."))
|
|
21
|
+
continue;
|
|
22
|
+
const rel = srcPath.startsWith(srcRoot + "/") ? srcPath.slice(srcRoot.length + 1) : srcPath;
|
|
23
|
+
const destPath = join(destRoot, rel);
|
|
24
|
+
if (existsSync(destPath) && !overwrite)
|
|
25
|
+
continue;
|
|
26
|
+
mkdirSync(dirname(destPath), { recursive: true });
|
|
27
|
+
copyFileSync(srcPath, destPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=copyDotfiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyDotfiles.js","sourceRoot":"","sources":["../src/copyDotfiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,QAAgB,EAAE,SAAS,GAAG,IAAI;IAC9E,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO;IACjC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAClF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACpB,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACtC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS;YAAE,SAAS;QACjD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { log } from "./log.js";
|
|
3
|
+
export function initializeGit(projectDir) {
|
|
4
|
+
try {
|
|
5
|
+
execFileSync("git", ["init", "-q"], { cwd: projectDir });
|
|
6
|
+
execFileSync("git", ["add", "."], { cwd: projectDir });
|
|
7
|
+
execFileSync("git", ["commit", "-q", "-m", "chore: initial scaffold from create-rv"], { cwd: projectDir });
|
|
8
|
+
log.ok("git initialized with initial commit");
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
log.warn(`git init skipped: ${err.message}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,IAAI,CAAC;QACH,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;QACzD,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;QACvD,YAAY,CACV,KAAK,EACL,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,wCAAwC,CAAC,EAChE,EAAE,GAAG,EAAE,UAAU,EAAE,CACpB,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,qCAAqC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseCli } from "./cli.js";
|
|
3
|
+
import { runInteractive } from "./prompts.js";
|
|
4
|
+
import { scaffold } from "./scaffold.js";
|
|
5
|
+
import { parseNameAndPath, ALL_EXTRAS, } from "./options.js";
|
|
6
|
+
import { log } from "./log.js";
|
|
7
|
+
async function main() {
|
|
8
|
+
const cli = parseCli(process.argv);
|
|
9
|
+
const defaults = {
|
|
10
|
+
projectName: cli.projectName ?? "my-app",
|
|
11
|
+
pkgManager: (cli.pkgManager ?? "npm"),
|
|
12
|
+
lang: (cli.lang ?? "ts"),
|
|
13
|
+
router: (cli.router ?? "react-router"),
|
|
14
|
+
extras: cli.extras.length > 0 ? cli.extras : ALL_EXTRAS.slice(),
|
|
15
|
+
git: cli.git,
|
|
16
|
+
install: cli.install,
|
|
17
|
+
};
|
|
18
|
+
const result = cli.yes || cli.pkgManager || cli.router || cli.lang || cli.extras.length > 0
|
|
19
|
+
? { ...defaults, extras: defaults.extras, install: cli.install, git: cli.git }
|
|
20
|
+
: await runInteractive(cli.projectName, defaults);
|
|
21
|
+
const [scopedAppName, dirName] = parseNameAndPath(result.projectName);
|
|
22
|
+
await scaffold({
|
|
23
|
+
projectName: dirName,
|
|
24
|
+
scopedAppName,
|
|
25
|
+
pkgManager: result.pkgManager,
|
|
26
|
+
git: result.git,
|
|
27
|
+
install: result.install,
|
|
28
|
+
extras: result.extras,
|
|
29
|
+
router: result.router,
|
|
30
|
+
lang: result.lang,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
main().catch((err) => {
|
|
34
|
+
log.err(err.message);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,gBAAgB,EAGhB,UAAU,GAGX,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG;QACf,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,QAAQ;QACxC,UAAU,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,KAAK,CAAe;QACnD,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAS;QAChC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,cAAc,CAAiB;QACtD,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,UAAkC,CAAC,KAAK,EAAE;QACxF,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,OAAO,EAAE,GAAG,CAAC,OAAO;KACrB,CAAC;IAEF,MAAM,MAAM,GACV,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAC1E,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;QAC9E,CAAC,CAAC,MAAM,cAAc,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAEtD,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAEtE,MAAM,QAAQ,CAAC;QACb,WAAW,EAAE,OAAO;QACpB,aAAa;QACb,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,GAAG,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("eslint", ctx.projectDir);
|
|
4
|
+
ctx.pkg.devDependencies["eslint"] = "latest";
|
|
5
|
+
ctx.pkg.devDependencies["@typescript-eslint/parser"] = "latest";
|
|
6
|
+
ctx.pkg.devDependencies["@typescript-eslint/eslint-plugin"] = "latest";
|
|
7
|
+
ctx.pkg.devDependencies["eslint-plugin-react"] = "latest";
|
|
8
|
+
ctx.pkg.devDependencies["eslint-plugin-react-hooks"] = "latest";
|
|
9
|
+
ctx.pkg.devDependencies["eslint-plugin-import"] = "latest";
|
|
10
|
+
ctx.pkg.devDependencies["eslint-plugin-simple-import-sort"] = "latest";
|
|
11
|
+
ctx.pkg.devDependencies["eslint-plugin-tailwindcss"] = "latest";
|
|
12
|
+
ctx.pkg.scripts["lint"] = "eslint .";
|
|
13
|
+
ctx.pkg.scripts["lint:fix"] = "eslint . --fix";
|
|
14
|
+
ctx.log("eslint wired (flat config, vercel style + import sort + tailwind)");
|
|
15
|
+
};
|
|
16
|
+
export { install };
|
|
17
|
+
//# sourceMappingURL=eslint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/installers/eslint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACtC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;IAC7C,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,2BAA2B,CAAC,GAAG,QAAQ,CAAC;IAChE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,kCAAkC,CAAC,GAAG,QAAQ,CAAC;IACvE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC;IAC1D,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,2BAA2B,CAAC,GAAG,QAAQ,CAAC;IAChE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,sBAAsB,CAAC,GAAG,QAAQ,CAAC;IAC3D,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,kCAAkC,CAAC,GAAG,QAAQ,CAAC;IACvE,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,2BAA2B,CAAC,GAAG,QAAQ,CAAC;IAChE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;IACrC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,gBAAgB,CAAC;IAC/C,GAAG,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;AAC/E,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { cpSync, existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { copyDotfiles } from "../copyDotfiles.js";
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
function findTemplatesDir(start) {
|
|
7
|
+
let cur = start;
|
|
8
|
+
for (let i = 0; i < 8; i++) {
|
|
9
|
+
const candidate = resolve(cur, "templates");
|
|
10
|
+
if (existsSync(candidate))
|
|
11
|
+
return candidate;
|
|
12
|
+
const parent = dirname(cur);
|
|
13
|
+
if (parent === cur)
|
|
14
|
+
break;
|
|
15
|
+
cur = parent;
|
|
16
|
+
}
|
|
17
|
+
throw new Error("could not locate templates/ directory");
|
|
18
|
+
}
|
|
19
|
+
const TEMPLATES_DIR = findTemplatesDir(__dirname);
|
|
20
|
+
const INSTALLER_FILES = {
|
|
21
|
+
query: "query.js",
|
|
22
|
+
zustand: "zustand.js",
|
|
23
|
+
rhf: "rhf.js",
|
|
24
|
+
zod: "zod.js",
|
|
25
|
+
eslint: "eslint.js",
|
|
26
|
+
prettier: "prettier.js",
|
|
27
|
+
shadcn: "shadcn.js",
|
|
28
|
+
};
|
|
29
|
+
const cache = new Map();
|
|
30
|
+
export async function getInstaller(key) {
|
|
31
|
+
if (cache.has(key))
|
|
32
|
+
return cache.get(key);
|
|
33
|
+
const file = INSTALLER_FILES[key];
|
|
34
|
+
const mod = (await import(`./${file}`));
|
|
35
|
+
cache.set(key, mod.install);
|
|
36
|
+
return mod.install;
|
|
37
|
+
}
|
|
38
|
+
export function copyOverlay(key, dest) {
|
|
39
|
+
const overlay = join(TEMPLATES_DIR, "extras", key);
|
|
40
|
+
if (!existsSync(overlay))
|
|
41
|
+
return false;
|
|
42
|
+
cpSync(overlay, dest, { recursive: true, force: true });
|
|
43
|
+
copyDotfiles(overlay, dest);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/installers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,SAAS,gBAAgB,CAAC,KAAa;IACrC,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC5C,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AAC3D,CAAC;AACD,MAAM,aAAa,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAiBlD,MAAM,eAAe,GAA6B;IAChD,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,YAAY;IACrB,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,MAAM,EAAE,WAAW;IACnB,QAAQ,EAAE,aAAa;IACvB,MAAM,EAAE,WAAW;CACpB,CAAC;AAEF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAa;IAC9C,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IAC3C,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAA2B,CAAC;IAClE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,IAAY;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("prettier", ctx.projectDir);
|
|
4
|
+
ctx.pkg.devDependencies["prettier"] = "latest";
|
|
5
|
+
ctx.pkg.devDependencies["prettier-plugin-tailwindcss"] = "latest";
|
|
6
|
+
ctx.pkg.scripts["format"] = "prettier --write .";
|
|
7
|
+
ctx.pkg.scripts["format:check"] = "prettier --check .";
|
|
8
|
+
ctx.log("prettier wired");
|
|
9
|
+
};
|
|
10
|
+
export { install };
|
|
11
|
+
//# sourceMappingURL=prettier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prettier.js","sourceRoot":"","sources":["../../src/installers/prettier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;IAC/C,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,6BAA6B,CAAC,GAAG,QAAQ,CAAC;IAClE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,oBAAoB,CAAC;IACjD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,oBAAoB,CAAC;IACvD,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("query", ctx.projectDir);
|
|
4
|
+
ctx.pkg.dependencies["@tanstack/react-query"] = "latest";
|
|
5
|
+
ctx.log("tanstack query wired (QueryClientProvider)");
|
|
6
|
+
};
|
|
7
|
+
export { install };
|
|
8
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/installers/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,uBAAuB,CAAC,GAAG,QAAQ,CAAC;IACzD,GAAG,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("rhf", ctx.projectDir);
|
|
4
|
+
ctx.pkg.dependencies["react-hook-form"] = "latest";
|
|
5
|
+
ctx.pkg.dependencies["@hookform/resolvers"] = "latest";
|
|
6
|
+
ctx.log("react-hook-form wired (example form in src/components/ExampleForm.tsx)");
|
|
7
|
+
};
|
|
8
|
+
export { install };
|
|
9
|
+
//# sourceMappingURL=rhf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rhf.js","sourceRoot":"","sources":["../../src/installers/rhf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC,GAAG,QAAQ,CAAC;IACnD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC;IACvD,GAAG,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAC;AACpF,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-react-router.js","sourceRoot":"","sources":["../../src/installers/router-react-router.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IAC5C,GAAG,CAAC,GAAG,CAAC,0FAA0F,CAAC,CAAC;AACtG,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const install = (ctx) => {
|
|
2
|
+
ctx.pkg.dependencies["@tanstack/react-router"] = "latest";
|
|
3
|
+
ctx.pkg.devDependencies["@tanstack/router-plugin"] = "latest";
|
|
4
|
+
ctx.log("tanstack router wired (file-based routes, vite plugin, routeTree.gen)");
|
|
5
|
+
};
|
|
6
|
+
export { install };
|
|
7
|
+
//# sourceMappingURL=router-tanstack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-tanstack.js","sourceRoot":"","sources":["../../src/installers/router-tanstack.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,wBAAwB,CAAC,GAAG,QAAQ,CAAC;IAC1D,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,yBAAyB,CAAC,GAAG,QAAQ,CAAC;IAC9D,GAAG,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;AACnF,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("router", ctx.projectDir);
|
|
4
|
+
ctx.pkg.dependencies["@tanstack/react-router"] = "latest";
|
|
5
|
+
ctx.pkg.devDependencies["@tanstack/router-plugin"] = "latest";
|
|
6
|
+
ctx.pkg.scripts["dev"] = "vite";
|
|
7
|
+
ctx.log("tanstack router wired (file-based routes, vite plugin)");
|
|
8
|
+
};
|
|
9
|
+
export { install };
|
|
10
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/installers/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACtC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,wBAAwB,CAAC,GAAG,QAAQ,CAAC;IAC1D,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,yBAAyB,CAAC,GAAG,QAAQ,CAAC;IAC9D,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;IAChC,GAAG,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;AACpE,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { copyOverlay } from "./index.js";
|
|
4
|
+
const install = (ctx) => {
|
|
5
|
+
copyOverlay("shadcn", ctx.projectDir);
|
|
6
|
+
ctx.pkg.dependencies["class-variance-authority"] = "latest";
|
|
7
|
+
ctx.pkg.dependencies["clsx"] = "latest";
|
|
8
|
+
ctx.pkg.dependencies["tailwind-merge"] = "latest";
|
|
9
|
+
ctx.pkg.dependencies["lucide-react"] = "latest";
|
|
10
|
+
ctx.pkg.dependencies["@radix-ui/react-slot"] = "latest";
|
|
11
|
+
ctx.pkg.devDependencies["tailwindcss-animate"] = "latest";
|
|
12
|
+
// flip components.json tsx flag based on lang
|
|
13
|
+
const cfgPath = join(ctx.projectDir, "components.json");
|
|
14
|
+
try {
|
|
15
|
+
const cfg = JSON.parse(readFileSync(cfgPath, "utf8"));
|
|
16
|
+
cfg.tsx = ctx.lang === "ts";
|
|
17
|
+
writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + "\n");
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// components.json absent — skip
|
|
21
|
+
}
|
|
22
|
+
ctx.log(`shadcn/ui primed (tailwind v4, tsx=${ctx.lang === "ts"}, cn() + Button/Card/Input)`);
|
|
23
|
+
};
|
|
24
|
+
export { install };
|
|
25
|
+
//# sourceMappingURL=shadcn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadcn.js","sourceRoot":"","sources":["../../src/installers/shadcn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACtC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,0BAA0B,CAAC,GAAG,QAAQ,CAAC;IAC5D,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,sBAAsB,CAAC,GAAG,QAAQ,CAAC;IACxD,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC;IAE1D,8CAA8C;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAsB,CAAC;QAC3E,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC;QAC5B,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IACD,GAAG,CAAC,GAAG,CAAC,sCAAsC,GAAG,CAAC,IAAI,KAAK,IAAI,6BAA6B,CAAC,CAAC;AAChG,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("zod", ctx.projectDir);
|
|
4
|
+
ctx.pkg.dependencies["zod"] = "latest";
|
|
5
|
+
ctx.log("zod wired (schemas in src/lib/schemas.ts)");
|
|
6
|
+
};
|
|
7
|
+
export { install };
|
|
8
|
+
//# sourceMappingURL=zod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod.js","sourceRoot":"","sources":["../../src/installers/zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACvC,GAAG,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { copyOverlay } from "./index.js";
|
|
2
|
+
const install = (ctx) => {
|
|
3
|
+
copyOverlay("zustand", ctx.projectDir);
|
|
4
|
+
ctx.pkg.dependencies["zustand"] = "latest";
|
|
5
|
+
ctx.log("zustand wired (sample store in src/lib/store.ts)");
|
|
6
|
+
};
|
|
7
|
+
export { install };
|
|
8
|
+
//# sourceMappingURL=zustand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zustand.js","sourceRoot":"","sources":["../../src/installers/zustand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEzD,MAAM,OAAO,GAAc,CAAC,GAAG,EAAE,EAAE;IACjC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACvC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC;IAC3C,GAAG,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
const isTTY = process.stdout.isTTY;
|
|
3
|
+
const dim = (s) => (isTTY ? pc.dim(s) : s);
|
|
4
|
+
const green = (s) => (isTTY ? pc.green(s) : s);
|
|
5
|
+
const red = (s) => (isTTY ? pc.red(s) : s);
|
|
6
|
+
const cyan = (s) => (isTTY ? pc.cyan(s) : s);
|
|
7
|
+
const bold = (s) => (isTTY ? pc.bold(s) : s);
|
|
8
|
+
export const log = {
|
|
9
|
+
info(msg) {
|
|
10
|
+
console.log(`${cyan("info")} ${msg}`);
|
|
11
|
+
},
|
|
12
|
+
ok(msg) {
|
|
13
|
+
console.log(`${green("done")} ${msg}`);
|
|
14
|
+
},
|
|
15
|
+
warn(msg) {
|
|
16
|
+
console.warn(`${dim("warn")} ${msg}`);
|
|
17
|
+
},
|
|
18
|
+
err(msg) {
|
|
19
|
+
console.error(`${red("fail")} ${msg}`);
|
|
20
|
+
},
|
|
21
|
+
step(label, msg) {
|
|
22
|
+
console.log(`${bold(label)} ${msg}`);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;AACnC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7D,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,EAAE,CAAC,GAAW;QACZ,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,GAAG,CAAC,GAAW;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,CAAC,KAAa,EAAE,GAAW;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;CACF,CAAC"}
|
package/dist/options.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const ALL_EXTRAS = [
|
|
2
|
+
"query",
|
|
3
|
+
"zustand",
|
|
4
|
+
"rhf",
|
|
5
|
+
"zod",
|
|
6
|
+
"eslint",
|
|
7
|
+
"prettier",
|
|
8
|
+
"shadcn",
|
|
9
|
+
];
|
|
10
|
+
export const VALID_PKG = ["npm", "pnpm", "yarn", "bun"];
|
|
11
|
+
export const ROUTER_CHOICES = ["tanstack", "react-router", "none"];
|
|
12
|
+
export const LANG_CHOICES = ["ts", "js"];
|
|
13
|
+
export function parseNameAndPath(input) {
|
|
14
|
+
const parts = input.split("/");
|
|
15
|
+
const dir = parts[parts.length - 1] ?? "my-app";
|
|
16
|
+
const scoped = parts.length > 1 ? `@${parts[0]}/${dir}` : dir;
|
|
17
|
+
return [scoped, dir];
|
|
18
|
+
}
|
|
19
|
+
export function isExtraKey(s) {
|
|
20
|
+
return ALL_EXTRAS.includes(s);
|
|
21
|
+
}
|
|
22
|
+
export function isRouterChoice(s) {
|
|
23
|
+
return ROUTER_CHOICES.includes(s);
|
|
24
|
+
}
|
|
25
|
+
export function isLang(s) {
|
|
26
|
+
return LANG_CHOICES.includes(s);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO;IACP,SAAS;IACT,KAAK;IACL,KAAK;IACL,QAAQ;IACR,UAAU;IACV,QAAQ;CACA,CAAC;AAKX,MAAM,CAAC,MAAM,SAAS,GAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,MAAM,CAAU,CAAC;AAG5E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,IAAI,CAAU,CAAC;AAclD,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9D,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAQ,UAAgC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,OAAQ,cAAoC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,CAAS;IAC9B,OAAQ,YAAkC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
export function getPkgManagerVersion(pm) {
|
|
3
|
+
try {
|
|
4
|
+
const out = execFileSync(pm, ["-v"], { encoding: "utf8" });
|
|
5
|
+
return out.trim();
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return "latest";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function pkgManagerField(pm) {
|
|
12
|
+
if (pm === "bun")
|
|
13
|
+
return undefined; // bun ignores the field
|
|
14
|
+
return `${pm}@${getPkgManagerVersion(pm)}`;
|
|
15
|
+
}
|
|
16
|
+
export function installCmd(pm) {
|
|
17
|
+
if (pm === "npm")
|
|
18
|
+
return ["npm", ["install"]];
|
|
19
|
+
if (pm === "pnpm")
|
|
20
|
+
return ["pnpm", ["install"]];
|
|
21
|
+
if (pm === "yarn")
|
|
22
|
+
return ["yarn", ["install"]];
|
|
23
|
+
return ["bun", ["install"]];
|
|
24
|
+
}
|
|
25
|
+
export function addCmd(pm, name, dev = false) {
|
|
26
|
+
if (pm === "npm")
|
|
27
|
+
return ["npm", [dev ? "install" : "install", "--save-dev", name]];
|
|
28
|
+
if (pm === "pnpm")
|
|
29
|
+
return ["pnpm", ["add", dev ? "-D" : "", name].filter(Boolean)];
|
|
30
|
+
if (pm === "yarn")
|
|
31
|
+
return ["yarn", [dev ? "add" : "add", name]];
|
|
32
|
+
return ["bun", ["add", name]];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=pkgManager.js.map
|