create-vexcms 0.1.0-alpha.10 → 0.1.0-alpha.12
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 +22 -11
- package/package.json +1 -1
- package/templates/base-nextjs/convex/auth/options.ts +9 -0
- package/templates/base-nextjs/package.json +6 -6
- package/templates/base-nextjs/src/components/providers/server.tsx +19 -6
- package/templates/marketing-site/convex/seed.ts +0 -11
- package/templates/marketing-site/src/vexcms/blocks/FAQ/config.ts +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# create-vexcms
|
|
2
2
|
|
|
3
|
+
> [!WARNING]
|
|
4
|
+
> `create-vexcms` is pre-release software, published only under the `alpha` npm
|
|
5
|
+
> dist-tag (`0.1.0-alpha.x`) — the `latest` tag on npm still points at an old,
|
|
6
|
+
> unrelated `0.0.20` line, so always scaffold with an explicit tag:
|
|
7
|
+
> `pnpm create vexcms@alpha`. Use it for experiments and evaluation only; the
|
|
8
|
+
> projects it scaffolds should not carry production traffic or real user data.
|
|
9
|
+
> Breaking changes land between alpha releases without deprecation cycles, and
|
|
10
|
+
> there is no migration path between alphas. See the
|
|
11
|
+
> [roadmap](https://docs.vexcms.dev) for what is and is not shipped.
|
|
12
|
+
|
|
3
13
|
Scaffolding CLI for [VexCMS](https://github.com/ianyimi/vex) projects. Creates a complete
|
|
4
14
|
Next.js application with a Convex backend, Better Auth authentication, and a self-hosted admin
|
|
5
15
|
panel — ready to run.
|
|
@@ -7,19 +17,19 @@ panel — ready to run.
|
|
|
7
17
|
## Usage
|
|
8
18
|
|
|
9
19
|
```bash
|
|
10
|
-
pnpm create vexcms@
|
|
20
|
+
pnpm create vexcms@alpha
|
|
11
21
|
```
|
|
12
22
|
|
|
13
23
|
Or with a project name:
|
|
14
24
|
|
|
15
25
|
```bash
|
|
16
|
-
pnpm create vexcms@
|
|
26
|
+
pnpm create vexcms@alpha my-project
|
|
17
27
|
```
|
|
18
28
|
|
|
19
29
|
Supports relative paths, including scaffolding straight into a monorepo app directory:
|
|
20
30
|
|
|
21
31
|
```bash
|
|
22
|
-
pnpm create vexcms@
|
|
32
|
+
pnpm create vexcms@alpha apps/website
|
|
23
33
|
```
|
|
24
34
|
|
|
25
35
|
## Flags
|
|
@@ -33,16 +43,16 @@ pnpm create vexcms@latest apps/website
|
|
|
33
43
|
|
|
34
44
|
```bash
|
|
35
45
|
# Empty project, no pre-built collections
|
|
36
|
-
pnpm create vexcms@
|
|
46
|
+
pnpm create vexcms@alpha my-app --bare
|
|
37
47
|
|
|
38
48
|
# Project with multi-tenant organizations
|
|
39
|
-
pnpm create vexcms@
|
|
49
|
+
pnpm create vexcms@alpha my-app --orgs
|
|
40
50
|
|
|
41
51
|
# Non-interactive, defaults only
|
|
42
|
-
pnpm create vexcms@
|
|
52
|
+
pnpm create vexcms@alpha my-app --yes
|
|
43
53
|
|
|
44
54
|
# Inside a pnpm workspace, catalog-aware
|
|
45
|
-
pnpm create vexcms@
|
|
55
|
+
pnpm create vexcms@alpha my-app --monorepo --yes
|
|
46
56
|
```
|
|
47
57
|
|
|
48
58
|
## Interactive prompts
|
|
@@ -157,7 +167,7 @@ Run from inside an existing pnpm workspace to scaffold a new app under it instea
|
|
|
157
167
|
standalone project:
|
|
158
168
|
|
|
159
169
|
```bash
|
|
160
|
-
pnpm create vexcms@
|
|
170
|
+
pnpm create vexcms@alpha my-app --monorepo --yes
|
|
161
171
|
```
|
|
162
172
|
|
|
163
173
|
The installer walks up from the current directory for the nearest `pnpm-workspace.yaml`, targets
|
|
@@ -168,11 +178,12 @@ versions), and skips both `git init` and dependency install — the root workspa
|
|
|
168
178
|
## Versioning
|
|
169
179
|
|
|
170
180
|
`create-vexcms` is versioned alongside every `@vexcms/*` package. Running
|
|
171
|
-
`pnpm create vexcms@
|
|
172
|
-
|
|
181
|
+
`pnpm create vexcms@alpha` always scaffolds with the newest pre-release. The npm
|
|
182
|
+
`latest` tag still points at an old, unrelated `0.0.20` line, so `@alpha` — or an
|
|
183
|
+
exact version — is the only way to get the current API:
|
|
173
184
|
|
|
174
185
|
```bash
|
|
175
|
-
pnpm create vexcms@0.1.0
|
|
186
|
+
pnpm create vexcms@0.1.0-alpha.10
|
|
176
187
|
```
|
|
177
188
|
|
|
178
189
|
The scaffolded project's `@vexcms/*` dependencies match the version of `create-vexcms` used to
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { BetterAuthOptions } from "better-auth"
|
|
2
2
|
|
|
3
|
+
import { anonRoleDatabaseHook } from "@vexcms/better-auth"
|
|
4
|
+
|
|
3
5
|
import {
|
|
4
6
|
TABLE_SLUG_ACCOUNTS,
|
|
5
7
|
TABLE_SLUG_SESSIONS,
|
|
@@ -15,6 +17,13 @@ export const authOptions: BetterAuthOptions = {
|
|
|
15
17
|
modelName: TABLE_SLUG_ACCOUNTS,
|
|
16
18
|
},
|
|
17
19
|
baseURL: process.env.SITE_URL,
|
|
20
|
+
databaseHooks: {
|
|
21
|
+
// Ties Better Auth's anonymous-plugin users to `access.anonRole` (see
|
|
22
|
+
// `~/auth/access.ts`) by stamping the same role explicitly, rather than
|
|
23
|
+
// relying solely on `roles`' `defaultValue` below — which every new user
|
|
24
|
+
// gets regardless of `isAnonymous`, anon-plugin or not.
|
|
25
|
+
user: anonRoleDatabaseHook(USER_ROLES.user),
|
|
26
|
+
},
|
|
18
27
|
// {{EMAIL_PASSWORD_AUTH}}
|
|
19
28
|
// {{OAUTH_PROVIDERS}}
|
|
20
29
|
plugins: createPlugins(),
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"@t3-oss/env-nextjs": "0.13.11",
|
|
25
25
|
"@tanstack/react-form": "1.33.1",
|
|
26
26
|
"@tanstack/react-query": "5.101.2",
|
|
27
|
-
"@vexcms/better-auth": "~0.1.0-alpha.
|
|
28
|
-
"@vexcms/core": "~0.1.0-alpha.
|
|
29
|
-
"@vexcms/file-storage-convex": "~0.1.0-alpha.
|
|
30
|
-
"@vexcms/next": "~0.1.0-alpha.
|
|
31
|
-
"@vexcms/react": "~0.1.0-alpha.
|
|
27
|
+
"@vexcms/better-auth": "~0.1.0-alpha.12",
|
|
28
|
+
"@vexcms/core": "~0.1.0-alpha.12",
|
|
29
|
+
"@vexcms/file-storage-convex": "~0.1.0-alpha.12",
|
|
30
|
+
"@vexcms/next": "~0.1.0-alpha.12",
|
|
31
|
+
"@vexcms/react": "~0.1.0-alpha.12",
|
|
32
32
|
"better-auth": "1.6.23",
|
|
33
33
|
"class-variance-authority": "0.7.1",
|
|
34
34
|
"clsx": "2.1.1",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@types/node": "20.19.43",
|
|
53
53
|
"@types/react": "19.2.17",
|
|
54
54
|
"@types/react-dom": "19.2.3",
|
|
55
|
-
"@vexcms/cli": "~0.1.0-alpha.
|
|
55
|
+
"@vexcms/cli": "~0.1.0-alpha.12",
|
|
56
56
|
"babel-plugin-react-compiler": "1.0.0",
|
|
57
57
|
"eslint": "9.39.5",
|
|
58
58
|
"eslint-config-next": "15.5.9",
|
|
@@ -3,16 +3,29 @@ import { NuqsAdapter } from "nuqs/adapters/next/app";
|
|
|
3
3
|
import { type PropsWithChildren } from "react";
|
|
4
4
|
|
|
5
5
|
import { AuthServerProvider } from "./auth";
|
|
6
|
-
import ConvexClientProvider from "./convex";
|
|
7
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Server-side provider shell.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately does **not** mount `ConvexClientProvider` — `ClientProviders`
|
|
11
|
+
* renders it, and `ClientProviders` is nested inside this component, so its
|
|
12
|
+
* copy is the one that actually reaches `children`. Mounting it here as well
|
|
13
|
+
* built a second `ConvexReactClient` + `QueryClient` pair on every server
|
|
14
|
+
* render (`providers/convex.tsx` intentionally creates fresh clients per call
|
|
15
|
+
* server-side to avoid cross-request leaks) whose only consumer was the
|
|
16
|
+
* discarded outer subtree.
|
|
17
|
+
*
|
|
18
|
+
* Nothing between here and `ClientProviders` needs Convex: `AuthServerProvider`
|
|
19
|
+
* is a server component that calls `getToken()`/`fetchAuthQuery` directly, and
|
|
20
|
+
* `NuqsAdapter` is unrelated. React context is unreadable from server
|
|
21
|
+
* components regardless.
|
|
22
|
+
*/
|
|
8
23
|
export default function ServerProviders({ children }: PropsWithChildren) {
|
|
9
24
|
return (
|
|
10
25
|
<ThemeProvider defaultTheme="system">
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
</AuthServerProvider>
|
|
15
|
-
</ConvexClientProvider>
|
|
26
|
+
<AuthServerProvider>
|
|
27
|
+
<NuqsAdapter>{children}</NuqsAdapter>
|
|
28
|
+
</AuthServerProvider>
|
|
16
29
|
</ThemeProvider>
|
|
17
30
|
);
|
|
18
31
|
}
|
|
@@ -572,15 +572,6 @@ export const init = internalMutation({
|
|
|
572
572
|
title: text({ label: "Title", required: true }),
|
|
573
573
|
slug: text({ label: "Slug", required: true, index: "by_slug" }),
|
|
574
574
|
excerpt: text({ label: "Excerpt" }),
|
|
575
|
-
status: select({
|
|
576
|
-
label: "Status",
|
|
577
|
-
options: [
|
|
578
|
-
{ label: "Draft", value: "draft" },
|
|
579
|
-
{ label: "Published", value: "published" },
|
|
580
|
-
],
|
|
581
|
-
defaultValue: ["draft"],
|
|
582
|
-
}),
|
|
583
|
-
publishedAt: date({ label: "Published At" }),
|
|
584
575
|
featured: checkbox({ label: "Featured" }),
|
|
585
576
|
readingMinutes: number({ label: "Reading Minutes" }),
|
|
586
577
|
coverImage: upload({ to: "images", label: "Cover Image" }),
|
|
@@ -612,8 +603,6 @@ export const posts = defineTable({
|
|
|
612
603
|
title: v.string(),
|
|
613
604
|
slug: v.string(),
|
|
614
605
|
excerpt: v.optional(v.string()),
|
|
615
|
-
status: v.optional(v.array(v.union(v.literal("draft"), v.literal("published")))),
|
|
616
|
-
publishedAt: v.optional(v.number()),
|
|
617
606
|
featured: v.optional(v.boolean()),
|
|
618
607
|
readingMinutes: v.optional(v.number()),
|
|
619
608
|
coverImage: v.optional(v.array(v.id("images"))),
|
|
@@ -35,7 +35,7 @@ export const faqBlock = defineBlock({
|
|
|
35
35
|
{
|
|
36
36
|
question: "What is Vex CMS?",
|
|
37
37
|
answer:
|
|
38
|
-
"Vex CMS is a headless content management system built on Convex. It provides real-time data, type-safe schemas,
|
|
38
|
+
"Vex CMS is a headless content management system built on Convex. It provides real-time data, type-safe schemas, database-driven theming, role-based access control, and a full admin panel — all configured in TypeScript. Versioning, drafts, and live preview are in progress; see the roadmap.",
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
question: "How is Vex different from other headless CMS platforms?",
|