convex-zen 1.14.0 → 1.15.1

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
@@ -2,73 +2,109 @@
2
2
 
3
3
  Production-grade authentication for Convex, built as a reusable component package.
4
4
 
5
- ## Import Distinction
5
+ `convex-zen` is a native Convex auth component and an alternative to:
6
6
 
7
- `convex-zen` is intentionally different from the Convex Better Auth integration:
7
+ - the Better Auth Convex component: https://github.com/get-convex/better-auth
8
+ - Convex Auth: https://labs.convex.dev/auth
8
9
 
9
- - Baseline reference: https://github.com/get-convex/better-auth
10
- - Baseline docs: https://labs.convex.dev/better-auth
11
- - This project: native auth implementation inside Convex components (`packages/convex-zen`), with framework-specific exports like `convex-zen/tanstack-start`, `convex-zen/next`, and `convex-zen/expo`.
10
+ ## Supported Today
12
11
 
13
- In short: we do not import Better Auth runtime into app code. We keep auth logic in Convex component functions and expose a familiar integration surface.
12
+ - Next.js App Router
13
+ - TanStack Start
14
14
 
15
- ## Packages
15
+ The canonical framework examples live in:
16
16
 
17
- ```bash
18
- npm install convex convex-zen
19
- ```
17
+ - `apps/next`
18
+ - `apps/tanstack`
20
19
 
21
- Built-in plugins are subpath exports from the main package:
20
+ ## Start Here
22
21
 
23
- ```ts
24
- import { systemAdminPlugin } from "convex-zen/plugins/system-admin";
25
- import { organizationPlugin } from "convex-zen/plugins/organization";
26
- ```
22
+ For agents and one-shot installs, start with:
27
23
 
28
- ## Workspace
24
+ 1. `LLMS.md`
25
+ 2. `npx convex-zen doctor`
26
+ 3. the scenario doc returned by `doctor`
29
27
 
30
- - Library package: `packages/convex-zen`
31
- - Demo apps: `apps/tanstack`, `apps/next`, `apps/expo`
32
- - Draft integration docs: `apps/docs`
33
- - Project architecture and design notes: `PROJECT.md`
28
+ Public install docs live under `apps/docs/external/install`.
29
+
30
+ ## Choose Your Starting Point
31
+
32
+ | Project state | Recommended command | Doc |
33
+ | --- | --- | --- |
34
+ | Existing Next.js app with Convex, no auth | `npx convex-zen doctor` | `apps/docs/external/install/next/add-to-existing-convex.md` |
35
+ | Existing TanStack Start app with Convex, no auth | `npx convex-zen doctor` | `apps/docs/external/install/tanstack-start/add-to-existing-convex.md` |
36
+ | Existing Next.js app using Convex Auth | `npx convex-zen doctor` | `apps/docs/external/install/next/migrate-from-convex-auth.md` |
37
+ | Existing TanStack Start app using Better Auth | `npx convex-zen doctor` | `apps/docs/external/install/tanstack-start/migrate-from-better-auth.md` |
38
+ | Framework app exists but Convex does not | `npx convex-zen doctor` | framework `from-scratch.md` guide |
39
+ | No supported framework app yet | read `apps/docs/external/install/README.md` | install overview |
40
+
41
+ ## Install Model
42
+
43
+ The canonical setup model is:
44
+
45
+ 1. author `convex/zen.config.ts`
46
+ 2. add `convex/auth.config.ts`
47
+ 3. run `npx convex-zen generate`
48
+ 4. wire the framework adapter to `convex/zen/_generated/meta.ts`
49
+ 5. mount the framework auth provider and auth route
50
+
51
+ Generated files in `convex/zen/*` are not hand-edited.
52
+
53
+ ## Key Files
34
54
 
35
- ## Quick start
55
+ User-authored:
56
+
57
+ - `convex/zen.config.ts`
58
+ - `convex/auth.config.ts`
59
+ - framework auth server/client files
60
+
61
+ Generated:
62
+
63
+ - `convex/zen/core.ts`
64
+ - `convex/zen/plugin/*`
65
+ - `convex/zen/_generated/auth.ts`
66
+ - `convex/zen/_generated/meta.ts`
67
+
68
+ ## Commands
69
+
70
+ Install the package in an app:
36
71
 
37
72
  ```bash
38
- pnpm install
39
- pnpm -C apps/tanstack exec convex dev
40
- pnpm -C apps/tanstack dev
73
+ pnpm add convex convex-zen
41
74
  ```
42
75
 
43
- The main authoring flow is:
76
+ Detect project state:
44
77
 
45
- - define your auth config in `convex/zen.config.ts` with `defineConvexZen(...)`
46
- - add the Convex auth bridge in `convex/auth.config.ts`
47
- - run `npx convex-zen generate`
48
- - wire your framework adapter to the generated refs and metadata
78
+ ```bash
79
+ npx convex-zen doctor
80
+ ```
49
81
 
50
- Expo example:
82
+ Generate Convex wrappers:
51
83
 
52
84
  ```bash
53
- pnpm -C apps/expo typecheck
54
- pnpm -C apps/expo build
55
- pnpm -C apps/expo start
85
+ npx convex-zen generate
56
86
  ```
57
87
 
58
- ## Testing and build
88
+ ## Workspace
89
+
90
+ - Library package: `packages/convex-zen`
91
+ - Demo apps: `apps/next`, `apps/tanstack`, `apps/expo`
92
+ - Public docs source: `apps/docs/external`
93
+ - Internal architecture notes: `apps/docs/internal`
94
+ - Project background: `PROJECT.md`
95
+
96
+ ## Testing and Build
59
97
 
60
98
  ```bash
61
99
  pnpm -C packages/convex-zen test
62
100
  pnpm -C packages/convex-zen build
63
101
  pnpm -C packages/convex-zen build:dist
102
+ pnpm -C apps/next build
64
103
  pnpm -C apps/tanstack build
65
- pnpm -C apps/expo build
66
104
  ```
67
105
 
68
- ## License and attribution
106
+ ## License and Attribution
69
107
 
70
108
  - Repository license: `LICENSE` (Apache License 2.0)
71
109
  - Required notices: `NOTICE`
72
110
  - Third-party provenance and notices: `THIRD_PARTY_NOTICES.md`
73
-
74
- When external code is copied or substantially adapted, source repo/path/commit and license details must be recorded in `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,21 @@
1
+ export type DoctorFramework = "next" | "tanstack-start" | "unknown";
2
+ export type DoctorState = "greenfield" | "existing-framework-no-convex" | "existing-framework-with-convex-no-auth" | "existing-framework-with-convex-auth" | "existing-framework-with-better-auth" | "existing-framework-with-other-auth" | "unknown";
3
+ export type FindingStatus = "ok" | "missing" | "warning" | "info";
4
+ export type RecommendedFlow = "choose-starting-point" | "install-convex-first" | "add-convex-zen" | "migrate-from-convex-auth" | "migrate-from-better-auth" | "migrate-from-other-auth" | "investigate-manually";
5
+ export interface DoctorFinding {
6
+ id: string;
7
+ status: FindingStatus;
8
+ path?: string;
9
+ message: string;
10
+ }
11
+ export interface DoctorResult {
12
+ cwd: string;
13
+ framework: DoctorFramework;
14
+ state: DoctorState;
15
+ findings: DoctorFinding[];
16
+ recommendedFlow: RecommendedFlow;
17
+ recommendedDocs: string[];
18
+ nextSteps: string[];
19
+ }
20
+ export declare function detectProject(cwd: string): Promise<DoctorResult>;
21
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/cli/detect.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;AACpE,MAAM,MAAM,WAAW,GACnB,YAAY,GACZ,8BAA8B,GAC9B,wCAAwC,GACxC,qCAAqC,GACrC,qCAAqC,GACrC,oCAAoC,GACpC,SAAS,CAAC;AACd,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAClE,MAAM,MAAM,eAAe,GACvB,uBAAuB,GACvB,sBAAsB,GACtB,gBAAgB,GAChB,0BAA0B,GAC1B,0BAA0B,GAC1B,yBAAyB,GACzB,sBAAsB,CAAC;AAE3B,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AA2eD,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAYtE"}
@@ -0,0 +1,423 @@
1
+ import { access, readFile, readdir, stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ const DOC_ROOT = "apps/docs/external/install";
4
+ async function pathExists(targetPath) {
5
+ try {
6
+ await access(targetPath);
7
+ return true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ async function readTextIfExists(targetPath) {
14
+ try {
15
+ return await readFile(targetPath, "utf8");
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ async function readPackageJson(cwd) {
22
+ const source = await readTextIfExists(path.join(cwd, "package.json"));
23
+ if (!source) {
24
+ return null;
25
+ }
26
+ try {
27
+ return JSON.parse(source);
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ function listPackageNames(packageJson) {
34
+ return new Set([
35
+ ...Object.keys(packageJson?.dependencies ?? {}),
36
+ ...Object.keys(packageJson?.devDependencies ?? {}),
37
+ ]);
38
+ }
39
+ async function findConfigMatch(cwd, candidates) {
40
+ for (const candidate of candidates) {
41
+ if (await pathExists(path.join(cwd, candidate))) {
42
+ return true;
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ async function collectSourceTexts(cwd) {
48
+ const queue = [
49
+ path.join(cwd, "package.json"),
50
+ path.join(cwd, "convex"),
51
+ path.join(cwd, "app"),
52
+ path.join(cwd, "src"),
53
+ ];
54
+ const texts = [];
55
+ while (queue.length > 0) {
56
+ const current = queue.shift();
57
+ if (!current || !(await pathExists(current))) {
58
+ continue;
59
+ }
60
+ const currentStat = await stat(current);
61
+ if (currentStat.isDirectory()) {
62
+ const entries = await readdir(current, { withFileTypes: true });
63
+ for (const entry of entries) {
64
+ if (entry.name.startsWith(".") || entry.name === "node_modules") {
65
+ continue;
66
+ }
67
+ queue.push(path.join(current, entry.name));
68
+ }
69
+ continue;
70
+ }
71
+ if (!/\.(cjs|cts|js|json|jsx|mjs|mts|ts|tsx)$/.test(current)) {
72
+ continue;
73
+ }
74
+ const source = await readTextIfExists(current);
75
+ if (source) {
76
+ texts.push(source);
77
+ }
78
+ }
79
+ return texts.join("\n");
80
+ }
81
+ function hasAnyNeedle(haystack, needles) {
82
+ return needles.some((needle) => haystack.includes(needle));
83
+ }
84
+ async function collectSignals(cwd) {
85
+ const packageJson = await readPackageJson(cwd);
86
+ const packageNames = listPackageNames(packageJson);
87
+ const [hasAppDir, hasSrcRoutesDir, hasConvexDir] = await Promise.all([
88
+ pathExists(path.join(cwd, "app")),
89
+ pathExists(path.join(cwd, "src", "routes")),
90
+ pathExists(path.join(cwd, "convex")),
91
+ ]);
92
+ const [hasNextConfig, hasViteConfig] = await Promise.all([
93
+ findConfigMatch(cwd, ["next.config.ts", "next.config.mjs", "next.config.js"]),
94
+ findConfigMatch(cwd, ["vite.config.ts", "vite.config.mjs", "vite.config.js"]),
95
+ ]);
96
+ const [hasConvexConfig, hasAuthConfig, hasZenConfig, hasZenGeneratedMeta, hasNextAuthRoute, hasNextAuthProvider, hasTanstackApiRoute, hasTanstackRouter, hasTanstackRootRoute,] = await Promise.all([
97
+ pathExists(path.join(cwd, "convex", "convex.config.ts")),
98
+ pathExists(path.join(cwd, "convex", "auth.config.ts")),
99
+ pathExists(path.join(cwd, "convex", "zen.config.ts")),
100
+ pathExists(path.join(cwd, "convex", "zen", "_generated", "meta.ts")),
101
+ pathExists(path.join(cwd, "app", "api", "auth", "[...auth]", "route.ts")),
102
+ pathExists(path.join(cwd, "app", "auth-provider.tsx")),
103
+ pathExists(path.join(cwd, "src", "routes", "api.auth.$.tsx")),
104
+ pathExists(path.join(cwd, "src", "router.tsx")),
105
+ pathExists(path.join(cwd, "src", "routes", "__root.tsx")),
106
+ ]);
107
+ let framework = "unknown";
108
+ if (packageNames.has("next") ||
109
+ hasAppDir ||
110
+ hasNextConfig ||
111
+ hasNextAuthRoute ||
112
+ hasNextAuthProvider) {
113
+ framework = "next";
114
+ }
115
+ else if (packageNames.has("@tanstack/react-start") ||
116
+ hasSrcRoutesDir ||
117
+ hasViteConfig ||
118
+ hasTanstackApiRoute ||
119
+ hasTanstackRouter ||
120
+ hasTanstackRootRoute) {
121
+ framework = "tanstack-start";
122
+ }
123
+ const sourceTexts = await collectSourceTexts(cwd);
124
+ const convexAuthDetected = packageNames.has("@convex-dev/auth") ||
125
+ hasAnyNeedle(sourceTexts, [
126
+ '"@convex-dev/auth"',
127
+ "'@convex-dev/auth'",
128
+ "convexAuth()",
129
+ "convexAuth(",
130
+ ]);
131
+ const betterAuthDetected = packageNames.has("@convex-dev/better-auth") ||
132
+ packageNames.has("better-auth") ||
133
+ packageNames.has("convex-better-auth") ||
134
+ hasAnyNeedle(sourceTexts, [
135
+ '"@convex-dev/better-auth"',
136
+ "'@convex-dev/better-auth'",
137
+ '"better-auth"',
138
+ "'better-auth'",
139
+ '"convex-better-auth"',
140
+ "'convex-better-auth'",
141
+ "betterAuth(",
142
+ "betterAuth.ts",
143
+ ]);
144
+ const genericAuthDetected = hasAnyNeedle(sourceTexts, [
145
+ '"next-auth"',
146
+ "'next-auth'",
147
+ '"@auth/core"',
148
+ "'@auth/core'",
149
+ '"@clerk/',
150
+ "'@clerk/",
151
+ '"lucia"',
152
+ "'lucia'",
153
+ '"auth0"',
154
+ "'auth0'",
155
+ '"supabase/auth',
156
+ "'supabase/auth",
157
+ ]) || packageNames.has("next-auth");
158
+ return {
159
+ framework,
160
+ hasPackageJson: packageJson !== null,
161
+ hasAppDir,
162
+ hasSrcRoutesDir,
163
+ hasNextConfig,
164
+ hasViteConfig,
165
+ hasConvexDir,
166
+ hasConvexConfig,
167
+ hasAuthConfig,
168
+ hasZenConfig,
169
+ hasZenGeneratedMeta,
170
+ hasNextAuthRoute,
171
+ hasNextAuthProvider,
172
+ hasTanstackApiRoute,
173
+ hasTanstackRouter,
174
+ hasTanstackRootRoute,
175
+ convexAuthDetected,
176
+ betterAuthDetected,
177
+ genericAuthDetected,
178
+ packageJson,
179
+ };
180
+ }
181
+ function resolveState(signals) {
182
+ if (signals.framework === "unknown") {
183
+ if (!signals.hasPackageJson && !signals.hasConvexDir) {
184
+ return "greenfield";
185
+ }
186
+ if (!signals.hasConvexDir && !signals.hasConvexConfig) {
187
+ return "unknown";
188
+ }
189
+ return "unknown";
190
+ }
191
+ if (!signals.hasConvexDir && !signals.hasConvexConfig) {
192
+ return "existing-framework-no-convex";
193
+ }
194
+ if (signals.betterAuthDetected) {
195
+ return "existing-framework-with-better-auth";
196
+ }
197
+ if (signals.convexAuthDetected) {
198
+ return "existing-framework-with-convex-auth";
199
+ }
200
+ if (signals.genericAuthDetected) {
201
+ return "existing-framework-with-other-auth";
202
+ }
203
+ return "existing-framework-with-convex-no-auth";
204
+ }
205
+ function frameworkLabel(framework) {
206
+ switch (framework) {
207
+ case "next":
208
+ return "Next.js";
209
+ case "tanstack-start":
210
+ return "TanStack Start";
211
+ default:
212
+ return "Unknown";
213
+ }
214
+ }
215
+ function buildFindings(signals, state) {
216
+ const findings = [
217
+ {
218
+ id: "framework",
219
+ status: signals.framework === "unknown" ? "warning" : "ok",
220
+ message: `Detected framework: ${frameworkLabel(signals.framework)}`,
221
+ },
222
+ {
223
+ id: "convex_dir",
224
+ status: signals.hasConvexDir ? "ok" : "missing",
225
+ path: "convex/",
226
+ message: signals.hasConvexDir
227
+ ? "Convex directory is present."
228
+ : "Convex directory is missing.",
229
+ },
230
+ {
231
+ id: "convex_config",
232
+ status: signals.hasConvexConfig ? "ok" : "missing",
233
+ path: "convex/convex.config.ts",
234
+ message: signals.hasConvexConfig
235
+ ? "Convex app config is present."
236
+ : "Convex app config is missing.",
237
+ },
238
+ {
239
+ id: "auth_config",
240
+ status: signals.hasAuthConfig ? "ok" : "missing",
241
+ path: "convex/auth.config.ts",
242
+ message: signals.hasAuthConfig
243
+ ? "Convex auth provider config is present."
244
+ : "Convex auth provider config is missing.",
245
+ },
246
+ {
247
+ id: "zen_config",
248
+ status: signals.hasZenConfig ? "ok" : "missing",
249
+ path: "convex/zen.config.ts",
250
+ message: signals.hasZenConfig
251
+ ? "convex-zen config is present."
252
+ : "convex-zen config is missing.",
253
+ },
254
+ {
255
+ id: "zen_generated_meta",
256
+ status: signals.hasZenGeneratedMeta ? "ok" : "missing",
257
+ path: "convex/zen/_generated/meta.ts",
258
+ message: signals.hasZenGeneratedMeta
259
+ ? "Generated convex-zen metadata is present."
260
+ : "Generated convex-zen metadata is missing. Run `npx convex-zen generate` after setup.",
261
+ },
262
+ ];
263
+ if (signals.framework === "next") {
264
+ findings.push({
265
+ id: "next_auth_route",
266
+ status: signals.hasNextAuthRoute ? "ok" : "missing",
267
+ path: "app/api/auth/[...auth]/route.ts",
268
+ message: signals.hasNextAuthRoute
269
+ ? "Next auth route handler is present."
270
+ : "Next auth route handler is missing.",
271
+ }, {
272
+ id: "next_auth_provider",
273
+ status: signals.hasNextAuthProvider ? "ok" : "missing",
274
+ path: "app/auth-provider.tsx",
275
+ message: signals.hasNextAuthProvider
276
+ ? "Next auth provider wiring is present."
277
+ : "Next auth provider wiring is missing.",
278
+ });
279
+ }
280
+ if (signals.framework === "tanstack-start") {
281
+ findings.push({
282
+ id: "tanstack_auth_route",
283
+ status: signals.hasTanstackApiRoute ? "ok" : "missing",
284
+ path: "src/routes/api.auth.$.tsx",
285
+ message: signals.hasTanstackApiRoute
286
+ ? "TanStack auth route is present."
287
+ : "TanStack auth route is missing.",
288
+ }, {
289
+ id: "tanstack_router",
290
+ status: signals.hasTanstackRouter ? "ok" : "missing",
291
+ path: "src/router.tsx",
292
+ message: signals.hasTanstackRouter
293
+ ? "TanStack router wiring is present."
294
+ : "TanStack router wiring is missing.",
295
+ }, {
296
+ id: "tanstack_root_route",
297
+ status: signals.hasTanstackRootRoute ? "ok" : "missing",
298
+ path: "src/routes/__root.tsx",
299
+ message: signals.hasTanstackRootRoute
300
+ ? "TanStack root route wiring is present."
301
+ : "TanStack root route wiring is missing.",
302
+ });
303
+ }
304
+ if (state === "existing-framework-with-convex-auth") {
305
+ findings.push({
306
+ id: "convex_auth_detected",
307
+ status: "warning",
308
+ message: "Detected Convex Auth markers. Use the dedicated migration guide.",
309
+ });
310
+ }
311
+ else if (state === "existing-framework-with-better-auth") {
312
+ findings.push({
313
+ id: "better_auth_detected",
314
+ status: "warning",
315
+ message: "Detected Better Auth markers. Use the dedicated migration guide.",
316
+ });
317
+ }
318
+ else if (state === "existing-framework-with-other-auth") {
319
+ findings.push({
320
+ id: "generic_auth_detected",
321
+ status: "warning",
322
+ message: "Detected other auth markers. Use the generic migration checklist and replace routes deliberately.",
323
+ });
324
+ }
325
+ return findings;
326
+ }
327
+ function resolveRecommendedDocs(framework, state) {
328
+ if (framework === "unknown") {
329
+ return [path.join(DOC_ROOT, "README.md")];
330
+ }
331
+ const frameworkRoot = path.join(DOC_ROOT, framework);
332
+ switch (state) {
333
+ case "greenfield":
334
+ return [path.join(DOC_ROOT, "README.md")];
335
+ case "existing-framework-no-convex":
336
+ return [path.join(frameworkRoot, "from-scratch.md")];
337
+ case "existing-framework-with-convex-no-auth":
338
+ return [path.join(frameworkRoot, "add-to-existing-convex.md")];
339
+ case "existing-framework-with-convex-auth":
340
+ return [path.join(frameworkRoot, "migrate-from-convex-auth.md")];
341
+ case "existing-framework-with-better-auth":
342
+ return [path.join(frameworkRoot, "migrate-from-better-auth.md")];
343
+ case "existing-framework-with-other-auth":
344
+ return [
345
+ path.join(DOC_ROOT, "shared", "migration-checklist.md"),
346
+ path.join(frameworkRoot, "add-to-existing-convex.md"),
347
+ ];
348
+ default:
349
+ return [path.join(DOC_ROOT, "README.md")];
350
+ }
351
+ }
352
+ function resolveRecommendedFlow(state) {
353
+ switch (state) {
354
+ case "greenfield":
355
+ return "choose-starting-point";
356
+ case "existing-framework-no-convex":
357
+ return "install-convex-first";
358
+ case "existing-framework-with-convex-no-auth":
359
+ return "add-convex-zen";
360
+ case "existing-framework-with-convex-auth":
361
+ return "migrate-from-convex-auth";
362
+ case "existing-framework-with-better-auth":
363
+ return "migrate-from-better-auth";
364
+ case "existing-framework-with-other-auth":
365
+ return "migrate-from-other-auth";
366
+ default:
367
+ return "investigate-manually";
368
+ }
369
+ }
370
+ function resolveNextSteps(framework, state) {
371
+ switch (state) {
372
+ case "greenfield":
373
+ return [
374
+ "Choose Next.js App Router or TanStack Start first.",
375
+ "Open apps/docs/external/install/README.md and pick the matching framework guide.",
376
+ ];
377
+ case "existing-framework-no-convex":
378
+ return [
379
+ "Install Convex into the existing app first.",
380
+ `Then follow ${path.posix.join(DOC_ROOT, framework, "from-scratch.md")} from the Convex step onward.`,
381
+ ];
382
+ case "existing-framework-with-convex-no-auth":
383
+ return [
384
+ "Create convex/zen.config.ts and convex/auth.config.ts.",
385
+ "Run npx convex-zen generate.",
386
+ `Follow ${path.posix.join(DOC_ROOT, framework, "add-to-existing-convex.md")}.`,
387
+ ];
388
+ case "existing-framework-with-convex-auth":
389
+ return [
390
+ "Inventory existing Convex Auth routes, env vars, and session reads.",
391
+ `Follow ${path.posix.join(DOC_ROOT, framework, "migrate-from-convex-auth.md")}.`,
392
+ ];
393
+ case "existing-framework-with-better-auth":
394
+ return [
395
+ "Inventory existing Better Auth routes, env vars, and data model usage.",
396
+ `Follow ${path.posix.join(DOC_ROOT, framework, "migrate-from-better-auth.md")}.`,
397
+ ];
398
+ case "existing-framework-with-other-auth":
399
+ return [
400
+ `Follow ${path.posix.join(DOC_ROOT, "shared", "migration-checklist.md")}.`,
401
+ `Then apply ${path.posix.join(DOC_ROOT, framework, "add-to-existing-convex.md")} once the old auth surface is isolated.`,
402
+ ];
403
+ default:
404
+ return [
405
+ "Project state is ambiguous.",
406
+ `Start with ${path.posix.join(DOC_ROOT, "README.md")} and inspect the example apps before editing.`,
407
+ ];
408
+ }
409
+ }
410
+ export async function detectProject(cwd) {
411
+ const signals = await collectSignals(cwd);
412
+ const state = resolveState(signals);
413
+ return {
414
+ cwd,
415
+ framework: signals.framework,
416
+ state,
417
+ findings: buildFindings(signals, state),
418
+ recommendedFlow: resolveRecommendedFlow(state),
419
+ recommendedDocs: resolveRecommendedDocs(signals.framework, state),
420
+ nextSteps: resolveNextSteps(signals.framework, state),
421
+ };
422
+ }
423
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/cli/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { DoctorResult } from "./detect.js";
2
+ export interface DoctorOptions {
3
+ cwd: string;
4
+ json: boolean;
5
+ }
6
+ export declare function runDoctor(options: DoctorOptions): Promise<DoctorResult>;
7
+ export declare function formatDoctorReport(result: DoctorResult): string;
8
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAE7E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAyB/D"}
@@ -0,0 +1,27 @@
1
+ import { detectProject } from "./detect.js";
2
+ export async function runDoctor(options) {
3
+ return detectProject(options.cwd);
4
+ }
5
+ export function formatDoctorReport(result) {
6
+ const lines = [
7
+ "convex-zen doctor",
8
+ ` framework: ${result.framework}`,
9
+ ` state: ${result.state}`,
10
+ ` recommended flow: ${result.recommendedFlow}`,
11
+ " findings:",
12
+ ];
13
+ for (const finding of result.findings) {
14
+ const suffix = finding.path ? ` (${finding.path})` : "";
15
+ lines.push(` - [${finding.status}] ${finding.message}${suffix}`);
16
+ }
17
+ lines.push(" docs:");
18
+ for (const doc of result.recommendedDocs) {
19
+ lines.push(` - ${doc}`);
20
+ }
21
+ lines.push(" next steps:");
22
+ for (const step of result.nextSteps) {
23
+ lines.push(` - ${step}`);
24
+ }
25
+ return lines.join("\n");
26
+ }
27
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAO5C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAsB;IACpD,OAAO,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAoB;IACrD,MAAM,KAAK,GAAa;QACtB,mBAAmB;QACnB,gBAAgB,MAAM,CAAC,SAAS,EAAE;QAClC,YAAY,MAAM,CAAC,KAAK,EAAE;QAC1B,uBAAuB,MAAM,CAAC,eAAe,EAAE;QAC/C,aAAa;KACd,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}