@betterstart/cli 0.1.41 → 0.1.43

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 CHANGED
@@ -1,260 +1,3 @@
1
1
  # @betterstart/cli
2
2
 
3
- > **Warning:** This project is a work in progress. Expect bugs, breaking changes, and incomplete features.
4
-
5
- Drop a production-ready CMS into any Next.js 16 app with one command. You get a full admin panel — auth, CRUD, rich text editing, file uploads, forms — living in a self-contained `cms/` directory. You own the code. No vendor lock-in.
6
-
7
- ```bash
8
- npx @betterstart/cli init
9
- ```
10
-
11
- ## What you get
12
-
13
- - **Admin panel** with sidebar navigation, search, filters, bulk actions, and CSV export
14
- - **Authentication** via Better Auth (email/password, role-based: admin, editor, member)
15
- - **22 field types** including rich text (TipTap), markdown (CodeMirror + Shiki), image/video uploads, relationships, tabs, groups, lists, and curriculum builder
16
- - **Public forms** with multi-step support, email notifications, Mailchimp integration, and a submissions admin
17
- - **Three schema types** — entities (full CRUD), singles (settings pages), and forms (public-facing with submission tracking)
18
- - **Caching** with Next.js 16 `'use cache'` directive, `cacheLife`, `cacheTag`, and `updateTag`
19
-
20
- ## Commands
21
-
22
- ### `betterstart init [name]`
23
-
24
- Scaffold the CMS into a new or existing Next.js project.
25
-
26
- ```bash
27
- betterstart init # Interactive setup in current project
28
- betterstart init my-app # Create new Next.js app + CMS
29
- betterstart init --preset blog -y # Non-interactive with blog preset
30
- ```
31
-
32
- **Presets:**
33
-
34
- | Preset | What it includes |
35
- |--------|-----------------|
36
- | `blank` | Settings singleton only |
37
- | `blog` | Settings + Categories + Posts (with many-to-many) |
38
- | `full` | Blog + Navigation + Contact form |
39
-
40
- Init runs 12 scaffolders in sequence: base directories, tsconfig aliases, Tailwind tokens, env vars, database, auth, UI components (206 files), layouts, API routes, linter config, dependency installation (~130 packages), and preset generation.
41
-
42
- ### `betterstart generate <schema>`
43
-
44
- Generate everything from a JSON schema file in `cms/schemas/`.
45
-
46
- ```bash
47
- betterstart generate posts # Entity CRUD (12 files)
48
- betterstart generate settings # Single-type page (7 files)
49
- betterstart generate contact # Form + admin (14 files)
50
- betterstart generate posts --force # Overwrite existing files
51
- betterstart generate posts --skip-migration # Skip drizzle-kit push
52
- ```
53
-
54
- Schema type is auto-detected: files in `schemas/forms/` or with `submitButtonText`/`steps` are forms, `type: "single"` is a single, everything else is an entity.
55
-
56
- ### `betterstart remove <schema>`
57
-
58
- Remove all generated files for a schema and clean up `schema.ts` + `navigation.ts`.
59
-
60
- ```bash
61
- betterstart remove posts
62
- ```
63
-
64
- ### `betterstart seed`
65
-
66
- Create an initial admin user interactively.
67
-
68
- ```bash
69
- betterstart seed
70
- ```
71
-
72
- ### `betterstart setup-r2`
73
-
74
- Configure Cloudflare R2 for file uploads.
75
-
76
- ### `betterstart update-deps`
77
-
78
- Install or update all CMS dependencies to their latest versions.
79
-
80
- ### `betterstart update-styles`
81
-
82
- Replace `cms-globals.css` with the latest version from the CLI templates.
83
-
84
- ## Generated file structure
85
-
86
- ```
87
- cms/
88
- db/schema.ts # Drizzle table definitions
89
- lib/actions/<name>.ts # Server actions (CRUD, search, filter, export)
90
- lib/cache/ # Cache tags, cached queries, revalidation
91
- hooks/use-<name>.ts # React Query hooks
92
- components/forms/ # Public form components
93
- lib/emails/ # React Email notification templates
94
- data/navigation.ts # Sidebar navigation config
95
-
96
- app/(cms)/cms/(authenticated)/
97
- <entity>/
98
- page.tsx # Server page with Suspense
99
- columns.tsx # TanStack Table column definitions
100
- <name>-table.tsx # Data table with pagination + sorting
101
- page-content.tsx # Client component (search, filters, bulk actions)
102
- <name>-form.tsx # Create/edit form with Zod validation
103
- new/page.tsx # Create page
104
- [id]/edit/page.tsx # Edit page
105
- forms/<form>/
106
- page.tsx # Submissions list
107
- [id]/page.tsx # View submission
108
- settings/page.tsx # Notification + export settings
109
- ```
110
-
111
- ## Schema examples
112
-
113
- ### Entity
114
-
115
- ```json
116
- {
117
- "name": "posts",
118
- "label": "Blog Posts",
119
- "icon": "FileText",
120
- "navGroup": { "label": "Blog", "icon": "BookOpen" },
121
- "fields": [
122
- { "name": "title", "type": "string", "label": "Title", "required": true },
123
- { "name": "slug", "type": "string", "label": "Slug", "hidden": true },
124
- { "name": "content", "type": "richtext", "label": "Content", "output": "html" },
125
- { "name": "image", "type": "image", "label": "Featured Image" },
126
- { "name": "published", "type": "boolean", "label": "Published" },
127
- {
128
- "name": "categories",
129
- "type": "relationship",
130
- "relationship": "categories",
131
- "label": "Categories",
132
- "multiple": true
133
- }
134
- ],
135
- "columns": [
136
- { "accessorKey": "title", "header": "Title", "type": "text", "sortable": true },
137
- { "accessorKey": "published", "header": "Status", "type": "badge" }
138
- ],
139
- "actions": { "create": true, "edit": true, "delete": true, "draft": true },
140
- "search": { "fields": ["title"] },
141
- "autoSlugify": { "enabled": true, "sourceField": "title", "targetField": "slug" }
142
- }
143
- ```
144
-
145
- ### Single
146
-
147
- ```json
148
- {
149
- "name": "settings",
150
- "type": "single",
151
- "label": "Settings",
152
- "icon": "Settings",
153
- "fields": [
154
- { "name": "siteName", "type": "string", "label": "Site Name" },
155
- { "name": "description", "type": "text", "label": "Description" }
156
- ]
157
- }
158
- ```
159
-
160
- ### Form (multi-step)
161
-
162
- ```json
163
- {
164
- "name": "candidateApplication",
165
- "label": "Candidate Applications",
166
- "icon": "UserPlus",
167
- "submitButtonText": "Submit Application",
168
- "successMessage": "Thanks for applying!",
169
- "notificationEmail": "hr@example.com",
170
- "steps": [
171
- {
172
- "name": "basicInfo",
173
- "label": "Basic Information",
174
- "fields": [
175
- { "name": "name", "type": "text", "label": "Full Name", "required": true },
176
- { "name": "email", "type": "email", "label": "Email", "required": true }
177
- ]
178
- },
179
- {
180
- "name": "experience",
181
- "label": "Experience",
182
- "fields": [
183
- { "name": "resume", "type": "upload", "label": "Resume" }
184
- ]
185
- }
186
- ]
187
- }
188
- ```
189
-
190
- ## Field types
191
-
192
- ### Entity/Single (22 types)
193
-
194
- | Category | Types |
195
- |----------|-------|
196
- | Text | `string`, `text`, `varchar` |
197
- | Rich content | `richtext`, `markdown` |
198
- | Numbers | `number`, `decimal`, `serial` |
199
- | Date/time | `date`, `timestamp`, `time` |
200
- | Boolean | `boolean` |
201
- | Media | `image`, `video`, `media`, `icon` |
202
- | Selection | `select`, `relationship` |
203
- | Layout | `group`, `tabs`, `separator` |
204
- | Complex | `list`, `curriculum` |
205
-
206
- ### Form (17 types)
207
-
208
- `text`, `textarea`, `email`, `phone`, `number`, `url`, `date`, `select`, `radio`, `checkbox`, `multiselect`, `file`, `upload`, `group`, `list`, `timezone`, `dynamicFields`
209
-
210
- ## Tech stack
211
-
212
- | Concern | Technology |
213
- |---------|-----------|
214
- | Framework | Next.js 16 (App Router) |
215
- | Database | Drizzle ORM + Neon PostgreSQL |
216
- | Auth | Better Auth |
217
- | UI | Radix primitives + Tailwind CSS v4 |
218
- | Rich text | TipTap |
219
- | Markdown | CodeMirror + Shiki + KaTeX |
220
- | Tables | TanStack React Table |
221
- | Data fetching | TanStack React Query |
222
- | Forms | React Hook Form + Zod |
223
- | URL state | nuqs |
224
- | Storage | Cloudflare R2 |
225
- | Email | Resend + React Email (opt-in) |
226
- | Icons | Lucide React |
227
-
228
- ## Configuration
229
-
230
- Create `cms.config.ts` in your project root (generated by `init`):
231
-
232
- ```typescript
233
- import { defineConfig } from '@betterstart/cli'
234
-
235
- export default defineConfig({
236
- database: {
237
- provider: 'neon',
238
- },
239
- features: {
240
- email: true,
241
- },
242
- })
243
- ```
244
-
245
- All generated code uses `@cms/*` path aliases:
246
-
247
- ```typescript
248
- import { db } from '@cms/db'
249
- import { posts } from '@cms/db/schema'
250
- import { getPosts } from '@cms/actions/posts'
251
- ```
252
-
253
- ## Requirements
254
-
255
- - Node.js >= 22
256
- - Next.js 16 with TypeScript and Tailwind CSS v4
257
-
258
- ## License
259
-
260
- MIT
3
+ > **Warning:** This project is a work in progress. Expect bugs, breaking changes, and incomplete features.