kitcn 0.0.1 → 0.12.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.
Files changed (93) hide show
  1. package/bin/intent.js +3 -0
  2. package/dist/aggregate/index.d.ts +388 -0
  3. package/dist/aggregate/index.js +37 -0
  4. package/dist/api-entry-BckXqaLb.js +66 -0
  5. package/dist/auth/client/index.d.ts +37 -0
  6. package/dist/auth/client/index.js +217 -0
  7. package/dist/auth/config/index.d.ts +45 -0
  8. package/dist/auth/config/index.js +24 -0
  9. package/dist/auth/generated/index.d.ts +2 -0
  10. package/dist/auth/generated/index.js +3 -0
  11. package/dist/auth/http/index.d.ts +64 -0
  12. package/dist/auth/http/index.js +461 -0
  13. package/dist/auth/index.d.ts +221 -0
  14. package/dist/auth/index.js +1398 -0
  15. package/dist/auth/nextjs/index.d.ts +50 -0
  16. package/dist/auth/nextjs/index.js +81 -0
  17. package/dist/auth-store-Cljlmdmi.js +197 -0
  18. package/dist/builder-CBdG5W6A.js +1974 -0
  19. package/dist/caller-factory-cTXNvYdz.js +216 -0
  20. package/dist/cli.mjs +13255 -0
  21. package/dist/codegen-lF80HSWu.mjs +3416 -0
  22. package/dist/context-utils-HPC5nXzx.d.ts +17 -0
  23. package/dist/create-schema-odyF4kCy.js +156 -0
  24. package/dist/create-schema-orm-DOyiNDCx.js +246 -0
  25. package/dist/crpc/index.d.ts +105 -0
  26. package/dist/crpc/index.js +169 -0
  27. package/dist/customFunctions-C0voKmtx.js +144 -0
  28. package/dist/error-BZEnI7Sq.js +41 -0
  29. package/dist/generated-contract-disabled-Cih4eITO.js +50 -0
  30. package/dist/generated-contract-disabled-D-sOFy92.d.ts +354 -0
  31. package/dist/http-types-DqJubRPJ.d.ts +292 -0
  32. package/dist/meta-utils-0Pu0Nrap.js +117 -0
  33. package/dist/middleware-BUybuv9n.d.ts +34 -0
  34. package/dist/middleware-C2qTZ3V7.js +84 -0
  35. package/dist/orm/index.d.ts +17 -0
  36. package/dist/orm/index.js +10713 -0
  37. package/dist/plugins/index.d.ts +2 -0
  38. package/dist/plugins/index.js +3 -0
  39. package/dist/procedure-caller-DtxLmGwA.d.ts +1467 -0
  40. package/dist/procedure-caller-MWcxhQDv.js +349 -0
  41. package/dist/query-context-B8o6-8kC.js +1518 -0
  42. package/dist/query-context-CFZqIvD7.d.ts +42 -0
  43. package/dist/query-options-Dw7cOyXl.js +121 -0
  44. package/dist/ratelimit/index.d.ts +269 -0
  45. package/dist/ratelimit/index.js +856 -0
  46. package/dist/ratelimit/react/index.d.ts +76 -0
  47. package/dist/ratelimit/react/index.js +183 -0
  48. package/dist/react/index.d.ts +1284 -0
  49. package/dist/react/index.js +2526 -0
  50. package/dist/rsc/index.d.ts +276 -0
  51. package/dist/rsc/index.js +233 -0
  52. package/dist/runtime-CtvJPkur.js +2453 -0
  53. package/dist/server/index.d.ts +5 -0
  54. package/dist/server/index.js +6 -0
  55. package/dist/solid/index.d.ts +1221 -0
  56. package/dist/solid/index.js +2940 -0
  57. package/dist/transformer-DtDhR3Lc.js +194 -0
  58. package/dist/types-BTb_4BaU.d.ts +42 -0
  59. package/dist/types-BiJE7qxR.d.ts +4 -0
  60. package/dist/types-DEJpkIhw.d.ts +88 -0
  61. package/dist/types-HhO_R6pd.d.ts +213 -0
  62. package/dist/validators-B7oIJCAp.js +279 -0
  63. package/dist/validators-vzRKjBJC.d.ts +88 -0
  64. package/dist/watcher.mjs +96 -0
  65. package/dist/where-clause-compiler-DdjN63Io.d.ts +4756 -0
  66. package/package.json +107 -35
  67. package/skills/convex/SKILL.md +486 -0
  68. package/skills/convex/references/features/aggregates.md +353 -0
  69. package/skills/convex/references/features/auth-admin.md +446 -0
  70. package/skills/convex/references/features/auth-organizations.md +1141 -0
  71. package/skills/convex/references/features/auth-polar.md +579 -0
  72. package/skills/convex/references/features/auth.md +470 -0
  73. package/skills/convex/references/features/create-plugins.md +153 -0
  74. package/skills/convex/references/features/http.md +676 -0
  75. package/skills/convex/references/features/migrations.md +162 -0
  76. package/skills/convex/references/features/orm.md +1166 -0
  77. package/skills/convex/references/features/react.md +657 -0
  78. package/skills/convex/references/features/scheduling.md +267 -0
  79. package/skills/convex/references/features/testing.md +209 -0
  80. package/skills/convex/references/setup/auth.md +501 -0
  81. package/skills/convex/references/setup/biome.md +190 -0
  82. package/skills/convex/references/setup/doc-guidelines.md +145 -0
  83. package/skills/convex/references/setup/index.md +759 -0
  84. package/skills/convex/references/setup/next.md +116 -0
  85. package/skills/convex/references/setup/react.md +175 -0
  86. package/skills/convex/references/setup/server.md +473 -0
  87. package/skills/convex/references/setup/start.md +67 -0
  88. package/LICENSE +0 -21
  89. package/README.md +0 -0
  90. package/dist/index.d.mts +0 -5
  91. package/dist/index.d.mts.map +0 -1
  92. package/dist/index.mjs +0 -6
  93. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,473 @@
1
+ ## 5. Core Backend
2
+
3
+ For production bootstrap, start in the CLI Registry: use `bunx kitcn init -t <next|vite> --yes` for the shortest fresh local path, `bunx kitcn init --yes` to adopt the current app and finish the first local Convex bootstrap in one command, and `bunx kitcn add <plugin>` for feature layers. This file is the manual backend wiring reference.
4
+
5
+ ### 5.1 Define schema and relations
6
+
7
+ **Create:** `convex/functions/schema.ts`
8
+
9
+ ```ts
10
+ import {
11
+ boolean,
12
+ convexTable,
13
+ defineSchema,
14
+ index,
15
+ text,
16
+ timestamp,
17
+ } from "kitcn/orm";
18
+
19
+ export const user = convexTable(
20
+ "user",
21
+ {
22
+ name: text().notNull(),
23
+ email: text().notNull(),
24
+ emailVerified: boolean().notNull(),
25
+ image: text(),
26
+ createdAt: timestamp().notNull().defaultNow(),
27
+ updatedAt: timestamp().notNull(),
28
+ role: text(),
29
+ banned: boolean(),
30
+ banReason: text(),
31
+ banExpires: timestamp(),
32
+ },
33
+ (t) => [index("email").on(t.email)]
34
+ );
35
+
36
+ export const session = convexTable(
37
+ "session",
38
+ {
39
+ token: text().notNull(),
40
+ userId: text()
41
+ .references(() => user.id, { onDelete: "cascade" })
42
+ .notNull(),
43
+ expiresAt: timestamp().notNull(),
44
+ createdAt: timestamp().notNull().defaultNow(),
45
+ updatedAt: timestamp().notNull(),
46
+ ipAddress: text(),
47
+ userAgent: text(),
48
+ impersonatedBy: text(),
49
+ },
50
+ (t) => [index("token").on(t.token), index("userId").on(t.userId)]
51
+ );
52
+
53
+ export const account = convexTable(
54
+ "account",
55
+ {
56
+ accountId: text().notNull(),
57
+ providerId: text().notNull(),
58
+ userId: text()
59
+ .references(() => user.id, { onDelete: "cascade" })
60
+ .notNull(),
61
+ accessToken: text(),
62
+ refreshToken: text(),
63
+ idToken: text(),
64
+ accessTokenExpiresAt: timestamp(),
65
+ refreshTokenExpiresAt: timestamp(),
66
+ scope: text(),
67
+ password: text(),
68
+ createdAt: timestamp().notNull().defaultNow(),
69
+ updatedAt: timestamp().notNull(),
70
+ },
71
+ (t) => [index("accountId").on(t.accountId), index("userId").on(t.userId)]
72
+ );
73
+
74
+ export const verification = convexTable(
75
+ "verification",
76
+ {
77
+ identifier: text().notNull(),
78
+ value: text().notNull(),
79
+ expiresAt: timestamp().notNull(),
80
+ createdAt: timestamp().notNull().defaultNow(),
81
+ updatedAt: timestamp().notNull(),
82
+ },
83
+ (t) => [index("identifier").on(t.identifier)]
84
+ );
85
+
86
+ export const jwks = convexTable("jwks", {
87
+ publicKey: text().notNull(),
88
+ privateKey: text().notNull(),
89
+ createdAt: timestamp().notNull().defaultNow(),
90
+ });
91
+
92
+ export const project = convexTable(
93
+ "project",
94
+ {
95
+ name: text().notNull(),
96
+ ownerId: text()
97
+ .references(() => user.id, { onDelete: "cascade" })
98
+ .notNull(),
99
+ createdAt: timestamp().notNull().defaultNow(),
100
+ updatedAt: timestamp().notNull(),
101
+ },
102
+ (t) => [index("ownerId_updatedAt").on(t.ownerId, t.updatedAt)]
103
+ );
104
+
105
+ export const tables = { user, session, account, verification, jwks, project };
106
+
107
+ export default defineSchema(tables, {
108
+ strict: false,
109
+ }).relations((r) => ({
110
+ user: {
111
+ projects: r.many.project(),
112
+ sessions: r.many.session(),
113
+ accounts: r.many.account(),
114
+ },
115
+ project: {
116
+ owner: r.one.user({ from: r.project.ownerId, to: r.user.id }),
117
+ },
118
+ session: {
119
+ user: r.one.user({ from: r.session.userId, to: r.user.id }),
120
+ },
121
+ account: {
122
+ user: r.one.user({ from: r.account.userId, to: r.user.id }),
123
+ },
124
+ }));
125
+ ```
126
+
127
+ ### 5.1.1 Reserved index fields (important)
128
+
129
+ Do not index `createdAt` directly in kitcn ORM examples.
130
+ `createdAt` maps to Convex internal `_creationTime`, and explicit indexes on it can fail.
131
+ Prefer `updatedAt` (or a dedicated sortable field) for custom index definitions.
132
+
133
+ ### 5.2 Attach ORM once (`ctx.orm`)
134
+
135
+ Do **not** create `convex/lib/orm.ts`.
136
+ `convex/functions/generated/` directory is generated and is the canonical server contract.
137
+ It includes `initCRPC` (from `generated/server`) and ORM helpers when schema relations metadata exists.
138
+ If you are not using codegen, use manual `initCRPC` from `kitcn/server` with `.dataModel()` and optional `.context()`.
139
+
140
+ Why this shape:
141
+
142
+ 1. `orm.with(ctx)` preserves query vs mutation capabilities in type space.
143
+ 2. It avoids common setup-time type failures like missing `insert`/`update` on `ctx.orm` in mutation handlers.
144
+
145
+ ### 5.3 Initialize cRPC and procedure builders
146
+
147
+ **Create:** `convex/lib/crpc.ts`
148
+
149
+ ```ts
150
+ import { initCRPC } from "../functions/generated/server";
151
+
152
+ const c = initCRPC
153
+ .meta<{
154
+ // Reserved for auth phase; do not implement auth logic yet.
155
+ auth?: "optional" | "required";
156
+ role?: "admin";
157
+ ratelimit?: string;
158
+ }>()
159
+ .create();
160
+
161
+ // Phase 1 baseline: public + private only.
162
+ // Do not add auth-aware builders until Section 6.9 and Section 11.3 pass.
163
+ export const publicQuery = c.query;
164
+ export const publicAction = c.action;
165
+ export const publicMutation = c.mutation;
166
+
167
+ export const privateQuery = c.query.internal();
168
+ export const privateMutation = c.mutation.internal();
169
+ export const privateAction = c.action.internal();
170
+
171
+ export const publicRoute = c.httpAction;
172
+ export const router = c.router;
173
+ ```
174
+
175
+ Phase ordering rule:
176
+
177
+ 1. Keep this non-auth baseline until Section 11.2 fully passes.
178
+ 2. Only then replace this file with the auth-aware variant in Section 6.9.
179
+
180
+ ### 5.4 Shared API/type helpers (generated)
181
+
182
+ Do **not** create `convex/shared/api.ts` manually.
183
+ It is generated by `kitcn dev`.
184
+
185
+ Generated exports include:
186
+
187
+ 1. `api` (typed procedure leaves + metadata)
188
+ 2. `Api`, `ApiInputs`, `ApiOutputs`
189
+ 3. `TableName`, `Select`, `Insert` (when `schema.ts` exports `tables`)
190
+
191
+ Consume these from `@convex/api` on app/client side.
192
+ Within Convex backend files, import server context/ORM helpers from `../functions/generated/server`.
193
+
194
+ ### 5.5 Start dev/codegen
195
+
196
+ Run:
197
+
198
+ ```bash
199
+ bunx kitcn dev
200
+ ```
201
+
202
+ If this requires interactive Convex setup, let `bunx kitcn dev` drive it first. Use `bunx convex init` only when you need to resolve deployment targeting separately.
203
+ Do not fake generated files.
204
+
205
+ Automation/non-interactive path:
206
+
207
+ 1. Run `bunx kitcn init --yes` when you want scaffold or adoption plus the one-shot local Convex bootstrap in one command.
208
+ 2. Run `bunx kitcn verify` when you want a non-interactive local runtime proof in the current app. It reuses an existing local deployment when one is already configured, and only falls back to anonymous fresh-local setup when it has to.
209
+ 3. Confirm the generated runtime exists in `convex/functions/generated/server.ts`.
210
+ 4. Then run `bunx kitcn dev` for ongoing codegen/API refresh.
211
+
212
+ Local deployment storage: New local and anonymous deployments store state under `.convex/` in the project root.
213
+
214
+ This generates:
215
+
216
+ - `convex/functions/_generated/*`
217
+ - `convex/functions/generated/` directory
218
+ - `convex/shared/api.ts`
219
+
220
+ Agent command policy:
221
+
222
+ 1. Default to `bunx kitcn dev`.
223
+ 2. `kitcn dev` already runs codegen/API generation.
224
+ 3. Do not run `bunx kitcn codegen` as a separate default step.
225
+ 4. Use `bunx kitcn verify` for one-shot local runtime proof in CI or agent runs.
226
+ 5. Use manual `bunx kitcn codegen` only as fallback when `kitcn dev` cannot be run and backend is already active.
227
+ 6. Use `bunx kitcn insights` for cloud-deployment debugging; it forwards to the upstream Convex insights CLI.
228
+
229
+ One-time codegen (optional; use only when `kitcn dev` is not running):
230
+
231
+ ```bash
232
+ bunx kitcn codegen
233
+ ```
234
+
235
+ Codegen runtime rule:
236
+
237
+ 1. `kitcn codegen` still requires a configured Convex deployment.
238
+ 2. If you need a runtime proof without a long-running dev session, use `bunx kitcn verify`.
239
+ 3. If you see `Local backend isn't running`, use `bunx kitcn verify` instead of hand-holding a second terminal.
240
+
241
+ ### 5.6 Import rules (hard requirement)
242
+
243
+ Never use lazy imports (`await import(...)`) in Convex code.
244
+
245
+ Rules:
246
+
247
+ 1. Convex files (`convex/functions/**`, `convex/lib/**`, `convex/routers/**`) must use static imports only.
248
+ 2. If generated modules are missing (`_generated/*`, `@convex/api`), stop and run `bunx kitcn dev` first.
249
+ 3. Do not work around missing generated files with dynamic imports.
250
+
251
+ ## 9. Optional Modules Setup (Feature Gates)
252
+
253
+ Enable only selected modules.
254
+
255
+ ### 9.0 Component composition rule (`convex/functions/convex.config.ts`)
256
+
257
+ When components are enabled, register them in one `defineApp()` file:
258
+
259
+ ```ts
260
+ import { defineApp } from "convex/server";
261
+ import myComponent from "some-component/convex.config";
262
+
263
+ const app = defineApp();
264
+
265
+ app.use(myComponent);
266
+
267
+ export default app;
268
+ ```
269
+
270
+ ### 9.1 RLS gate
271
+
272
+ Use `rlsPolicy` on ORM tables, evaluate through ORM context:
273
+
274
+ ```ts
275
+ import { convexTable, id, rlsPolicy, text, eq } from "kitcn/orm";
276
+
277
+ export const secret = convexTable.withRLS(
278
+ "secret",
279
+ {
280
+ ownerId: id("user").notNull(),
281
+ value: text().notNull(),
282
+ },
283
+ (t) => [
284
+ rlsPolicy("read_own", {
285
+ for: "select",
286
+ using: (ctx) => eq(t.ownerId, ctx.viewerId),
287
+ }),
288
+ ]
289
+ );
290
+ ```
291
+
292
+ ### 9.2 Schema triggers gate
293
+
294
+ ```ts
295
+ import { convexTable, defineTriggers, text } from "kitcn/orm";
296
+
297
+ const triggers = defineTriggers(relations, {
298
+ post: {
299
+ change: async (change, ctx) => {
300
+ if (change.operation === "delete") return;
301
+ // side effects here
302
+ },
303
+ },
304
+ });
305
+ ```
306
+
307
+ Trigger guardrails:
308
+
309
+ 1. Keep trigger work bounded and idempotent.
310
+ 2. Avoid trigger chains that re-query/rewrite the same hot table rows during seed/init flows.
311
+ 3. If `internal.seed.seed` or `internal.init.default` hangs, move counter/invariant sync into explicit mutation helpers and seed reconciliation.
312
+
313
+ ### 9.3 Aggregates gate
314
+
315
+ Declare `aggregateIndex` and/or `rankIndex` in table definitions. Backfill runs automatically via `kitcn dev`.
316
+
317
+ ```ts
318
+ // convex/functions/schema.ts
319
+ const postLikes = convexTable(
320
+ "postLikes",
321
+ { postId: text().notNull(), userId: text().notNull() },
322
+ (t) => [aggregateIndex("by_post").on(t.postId)]
323
+ );
324
+
325
+ const scores = convexTable(
326
+ "scores",
327
+ { gameId: text().notNull(), score: integer().notNull() },
328
+ (t) => [
329
+ rankIndex("leaderboard")
330
+ .partitionBy(t.gameId)
331
+ .orderBy({ column: t.score, direction: "desc" }),
332
+ ]
333
+ );
334
+ ```
335
+
336
+ No trigger wiring needed — `aggregateIndex` and `rankIndex` are maintained automatically by the ORM.
337
+
338
+ If Aggregates are **disabled**, remove `aggregateIndex`/`rankIndex` declarations from table definitions and re-run `bunx kitcn verify`.
339
+
340
+ ### 9.4 Rate limiting gate
341
+
342
+ Use the built-in package module (no component registration):
343
+
344
+ ```bash
345
+ bun add kitcn
346
+ ```
347
+
348
+ `aggregateExtension` and `migrationExtension` are builtin in `defineSchema`.
349
+ Rate limiting is opt-in: scaffold the full starter once.
350
+
351
+ ```bash
352
+ bunx kitcn add ratelimit
353
+ ```
354
+
355
+ This creates `convex/lib/plugins/ratelimit/schema.ts`, `convex/lib/plugins/ratelimit/plugin.ts`, and registers `ratelimitExtension()` in `convex/functions/schema.ts`.
356
+
357
+ ```ts
358
+ import { defineSchema } from "kitcn/orm";
359
+ import { ratelimitExtension } from "../lib/plugins/ratelimit/schema";
360
+
361
+ export default defineSchema(tables).extend(ratelimitExtension());
362
+ ```
363
+
364
+ Create `convex/lib/plugins/ratelimit/plugin.ts` and call `ratelimit.middleware()` from mutation builders. Use the default bucket for normal writes and reserve `.meta({ ratelimit: ... })` for named overrides.
365
+
366
+ Use `RatelimitPlugin` from `kitcn/ratelimit`:
367
+
368
+ ```ts
369
+ import { getSessionNetworkSignals } from "kitcn/auth";
370
+ import { MINUTE, Ratelimit, RatelimitPlugin } from "kitcn/ratelimit";
371
+ import type { MutationCtx } from "../../../functions/generated/server";
372
+ import type { Select } from "../../../shared/api";
373
+
374
+ const fixed = (rate: number) => Ratelimit.fixedWindow(rate, MINUTE);
375
+
376
+ export const ratelimitBuckets = {
377
+ default: {
378
+ public: fixed(30),
379
+ free: fixed(60),
380
+ premium: fixed(200),
381
+ },
382
+ } as const;
383
+
384
+ type RatelimitTier = keyof (typeof ratelimitBuckets)["default"];
385
+ export type RatelimitBucket = keyof typeof ratelimitBuckets;
386
+
387
+ type RatelimitUser = {
388
+ id: string;
389
+ isAdmin?: boolean;
390
+ plan?: "premium" | "team" | null;
391
+ session?: Select<"session"> | null;
392
+ };
393
+
394
+ type RatelimitCtx = MutationCtx & {
395
+ user?: RatelimitUser | null;
396
+ };
397
+
398
+ type RatelimitMeta = {
399
+ ratelimit?: RatelimitBucket;
400
+ };
401
+
402
+ export function getUserTier(user: RatelimitUser | null): RatelimitTier {
403
+ if (!user) return "public";
404
+ if (user.isAdmin || user.plan) return "premium";
405
+ return "free";
406
+ }
407
+
408
+ export const ratelimit = RatelimitPlugin.configure({
409
+ buckets: ratelimitBuckets,
410
+ getBucket: ({ meta }: { meta: RatelimitMeta }) => meta.ratelimit ?? "default",
411
+ getUser: ({ ctx }: { ctx: RatelimitCtx }) => ctx.user ?? null,
412
+ getIdentifier: ({ user }: { user: RatelimitUser | null }) =>
413
+ user?.id ?? "anonymous",
414
+ getTier: getUserTier,
415
+ getSignals: ({
416
+ ctx,
417
+ user,
418
+ }: {
419
+ ctx: RatelimitCtx;
420
+ user: RatelimitUser | null;
421
+ }) => getSessionNetworkSignals(ctx, user?.session ?? null),
422
+ prefix: ({ bucket, tier }) => `ratelimit:${bucket}:${tier}`,
423
+ failureMode: "closed",
424
+ enableProtection: true,
425
+ denyListThreshold: 30,
426
+ });
427
+ ```
428
+
429
+ ### 9.5 Scheduling gate
430
+
431
+ Create `convex/functions/crons.ts` with `cronJobs()` and use `caller.schedule.now/after/at` in mutations/actions for delayed procedure jobs (`ctx.scheduler.*` only for raw `internal.*` functions).
432
+
433
+ ### 9.6 HTTP router gate
434
+
435
+ If REST endpoints are needed, add cRPC route builders and register routers in `convex/functions/http.ts`; consume via `crpc.http.*` client proxies.
436
+
437
+ ### 9.7 Email + Resend gate
438
+
439
+ Install packages:
440
+
441
+ ```bash
442
+ bun add @kitcn/resend
443
+ ```
444
+
445
+ `kitcn add resend` scaffolds `convex/lib/plugins/resend/schema.ts` and registers `resendExtension()` in `convex/functions/schema.ts`.
446
+
447
+ If `paths.env` is missing, the add flow also bootstraps `convex/lib/get-env.ts`, writes `paths.env` into `kitcn.json`, and adds resend env fields there. The schema keeps `RESEND_API_KEY` optional for local dev flow, and the add command reminds you to set it in `convex/.env` before sending email. Webhook secret and default sender stay optional.
448
+
449
+ ```ts
450
+ import { resendExtension } from "../lib/plugins/resend/schema";
451
+
452
+ export default defineSchema(tables).extend(resendExtension());
453
+ ```
454
+
455
+ Scaffold resend runtime + helpers:
456
+
457
+ ```bash
458
+ bunx kitcn add resend
459
+ ```
460
+
461
+ Recommended files for this gate:
462
+
463
+ - `convex/functions/plugins/resend.ts`
464
+ - `convex/functions/plugins/email.tsx`
465
+ - `convex/lib/plugins/resend/plugin.ts`
466
+ - `convex/lib/plugins/resend/webhook.ts`
467
+ - `convex/lib/plugins/resend/crons.ts`
468
+
469
+ If `plugins/email.tsx` is selected, install React Email deps:
470
+
471
+ ```bash
472
+ bun add @react-email/components @react-email/render react-email react react-dom
473
+ ```
@@ -0,0 +1,67 @@
1
+ ## 8.B TanStack Start
2
+
3
+ Explicit exception: current docs still use `@convex-dev/better-auth/*` helpers for TanStack Start integration.
4
+
5
+ ### 8.B.1 Auth client + auth server helpers
6
+
7
+ **Create:** `src/lib/convex/auth/auth-client.ts`
8
+
9
+ ```ts
10
+ import type { Auth } from "@convex/auth-shared";
11
+ import { convexClient } from "@convex-dev/better-auth/client/plugins";
12
+ import { adminClient, inferAdditionalFields } from "better-auth/client/plugins";
13
+ import { createAuthClient } from "better-auth/react";
14
+
15
+ export const authClient = createAuthClient({
16
+ baseURL:
17
+ typeof window === "undefined"
18
+ ? (import.meta.env.VITE_SITE_URL as string | undefined)
19
+ : window.location.origin,
20
+ sessionOptions: { refetchOnWindowFocus: false },
21
+ plugins: [inferAdditionalFields<Auth>(), adminClient(), convexClient()],
22
+ });
23
+ ```
24
+
25
+ **Create:** `src/lib/convex/auth/auth-server.ts`
26
+
27
+ ```ts
28
+ import { convexBetterAuthReactStart } from "@convex-dev/better-auth/react-start";
29
+
30
+ export const {
31
+ handler,
32
+ getToken,
33
+ fetchAuthQuery,
34
+ fetchAuthMutation,
35
+ fetchAuthAction,
36
+ } = convexBetterAuthReactStart({
37
+ convexUrl: process.env.VITE_CONVEX_URL!,
38
+ convexSiteUrl: process.env.VITE_CONVEX_SITE_URL!,
39
+ });
40
+ ```
41
+
42
+ ### 8.B.2 Auth API endpoint
43
+
44
+ **Create:** `src/routes/api/auth/$.ts`
45
+
46
+ ```ts
47
+ import { createFileRoute } from "@tanstack/react-router";
48
+ import { handler } from "@/lib/convex/auth/auth-server";
49
+
50
+ export const Route = createFileRoute("/api/auth/$")({
51
+ server: {
52
+ handlers: {
53
+ GET: ({ request }) => handler(request),
54
+ POST: ({ request }) => handler(request),
55
+ },
56
+ },
57
+ });
58
+ ```
59
+
60
+ ### 8.B.3 Caller/context and providers
61
+
62
+ Use docs pattern from `tanstack-start.mdx` for:
63
+
64
+ - `createCallerFactory` + `runServerCall`
65
+ - router context values (`convex`, `queryClient`, `convexQueryClient`)
66
+ - provider wrapping with `ConvexAuthProvider` and `initialToken`
67
+
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- zbeyens
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
package/README.md DELETED
File without changes
package/dist/index.d.mts DELETED
@@ -1,5 +0,0 @@
1
- //#region src/index.d.ts
2
- declare const hello: () => string;
3
- //#endregion
4
- export { hello };
5
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";cAAa"}
package/dist/index.mjs DELETED
@@ -1,6 +0,0 @@
1
- //#region src/index.ts
2
- const hello = () => "hello";
3
-
4
- //#endregion
5
- export { hello };
6
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export const hello = () => 'hello';\n"],"mappings":";AAAA,MAAa,cAAc"}