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 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@latest
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@latest my-project
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@latest apps/website
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@latest my-app --bare
46
+ pnpm create vexcms@alpha my-app --bare
37
47
 
38
48
  # Project with multi-tenant organizations
39
- pnpm create vexcms@latest my-app --orgs
49
+ pnpm create vexcms@alpha my-app --orgs
40
50
 
41
51
  # Non-interactive, defaults only
42
- pnpm create vexcms@latest my-app --yes
52
+ pnpm create vexcms@alpha my-app --yes
43
53
 
44
54
  # Inside a pnpm workspace, catalog-aware
45
- pnpm create vexcms@latest my-app --monorepo --yes
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@latest my-app --monorepo --yes
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@latest` always scaffolds with the latest package versions; pin a specific
172
- release the same way:
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,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vexcms",
3
- "version": "0.1.0-alpha.10",
3
+ "version": "0.1.0-alpha.12",
4
4
  "description": "Scaffold a new VexCMS project",
5
5
  "keywords": [
6
6
  "cms",
@@ -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.10",
28
- "@vexcms/core": "~0.1.0-alpha.10",
29
- "@vexcms/file-storage-convex": "~0.1.0-alpha.10",
30
- "@vexcms/next": "~0.1.0-alpha.10",
31
- "@vexcms/react": "~0.1.0-alpha.10",
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.10",
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
- <ConvexClientProvider>
12
- <AuthServerProvider>
13
- <NuqsAdapter>{children}</NuqsAdapter>
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, draft/publish workflows, live preview, and a beautiful admin panel — all configured with TypeScript.",
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?",