kitcn 0.33.6 → 0.33.8
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/CHANGELOG.md +28 -0
- package/dist/aggregate/index.d.ts +1 -1
- package/dist/auth/client/index.d.ts +45 -21
- package/dist/auth/client/index.js +203 -111
- package/dist/auth/generated/index.d.ts +1 -1
- package/dist/auth/index.d.ts +16 -16
- package/dist/auth/nextjs/index.d.ts +3 -3
- package/dist/auth/nextjs/index.js +3 -2
- package/dist/auth/start/index.js +134 -2
- package/dist/auth/start/server/index.d.ts +1 -1
- package/dist/auth/start/server/index.js +1 -1
- package/dist/crpc/index.d.ts +2 -2
- package/dist/crpc/index.js +2 -2
- package/dist/{generated-contract-disabled-PdNGvNYP.d.ts → generated-contract-disabled-CFLQf8Wg.d.ts} +25 -25
- package/dist/orm/index.d.ts +1 -1
- package/dist/orm/migrations/index.d.ts +1 -1
- package/dist/{query-options-DGG93--5.js → query-options-YkFvau71.js} +6 -2
- package/dist/react/index.js +149 -140
- package/dist/rsc/index.d.ts +1 -1
- package/dist/rsc/index.js +1 -1
- package/dist/solid/index.js +4 -1
- package/dist/{token-tlbNKQS0.d.ts → token-COZD00dG.d.ts} +2 -1
- package/dist/{token-CgIvcEZX.js → token-CZbuEcTL.js} +13 -4
- package/dist/{auth-store-x3_wvhTR.js → token-gate-CEzbXArg.js} +178 -1
- package/dist/{types-C7JkpfeY.d.ts → types-Bb0kwteA.d.ts} +5 -1
- package/dist/{where-clause-compiler-BzAJnWt4.d.ts → where-clause-compiler-CTblNxLo.d.ts} +24 -24
- package/package.json +1 -1
- package/skills/kitcn/references/features/auth.md +26 -8
- package/skills/kitcn/references/features/react.md +5 -1
- package/skills/kitcn/references/setup/next.md +48 -1
|
@@ -64,6 +64,10 @@ declare function replaceUrlParam(url: string, params: Record<string, string>): s
|
|
|
64
64
|
* Handles array values as multiple params with same key (like Hono).
|
|
65
65
|
*/
|
|
66
66
|
declare function buildSearchParams(query: Record<string, string | string[]>): URLSearchParams;
|
|
67
|
+
declare const RECHECK_AUTHORIZATION: unique symbol;
|
|
68
|
+
declare const withAuthorizationRecheck: <T extends {
|
|
69
|
+
[key: string]: string | undefined;
|
|
70
|
+
}>(headers: T, recheck: () => boolean) => T;
|
|
67
71
|
/**
|
|
68
72
|
* Hono-style HTTP request executor.
|
|
69
73
|
* Processes args in the same way as Hono's ClientRequestImpl.fetch().
|
|
@@ -210,4 +214,4 @@ type VanillaAction<T extends FunctionReference<'action'>> = {
|
|
|
210
214
|
mutate: keyof FunctionArgs<T> extends never ? (args?: EmptyObject) => Promise<FunctionReturnType<T>> : EmptyObject extends FunctionArgs<T> ? (args?: FunctionArgs<T>) => Promise<FunctionReturnType<T>> : (args: FunctionArgs<T>) => Promise<FunctionReturnType<T>>;
|
|
211
215
|
};
|
|
212
216
|
//#endregion
|
|
213
|
-
export { HttpInputArgs as A, ReservedMutationOptions as C, VanillaMutation as D, VanillaAction as E,
|
|
217
|
+
export { HttpInputArgs as A, ReservedMutationOptions as C, VanillaMutation as D, VanillaAction as E, executeHttpRequest as F, replaceUrlParam as I, withAuthorizationRecheck as L, RECHECK_AUTHORIZATION as M, RESERVED_KEYS as N, HttpClientOptions as O, buildSearchParams as P, ReservedInfiniteQueryOptions as S, StaticQueryOptsParam as T, IsPaginated as _, BaseInfiniteQueryOptsParam as a, PaginatedFnMeta as b, ConvexMutationKey as c, ConvexQueryMeta as d, EmptyObject as f, InfiniteQueryInput as g, FnMeta as h, BaseConvexQueryOptions as i, HttpProxyBaseOptions as j, HttpFormValue as k, ConvexQueryHookOptions as l, FUNC_REF_SYMBOL as m, BaseConvexActionOptions as n, ConvexActionKey as o, ExtractPaginatedItem as p, BaseConvexInfiniteQueryOptions as r, ConvexInfiniteQueryMeta as s, AuthType as t, ConvexQueryKey as u, Meta as v, ReservedQueryOptions as w, PaginationOpts as x, MutationVariables as y };
|
|
@@ -102,22 +102,22 @@ declare const migrationStorageTables: {
|
|
|
102
102
|
fieldName: "status";
|
|
103
103
|
};
|
|
104
104
|
};
|
|
105
|
-
|
|
105
|
+
cursor: ConvexTextBuilderInitial<""> & {
|
|
106
106
|
_: {
|
|
107
107
|
tableName: "migration_state";
|
|
108
108
|
};
|
|
109
109
|
} & {
|
|
110
110
|
_: {
|
|
111
|
-
fieldName: "
|
|
111
|
+
fieldName: "cursor";
|
|
112
112
|
};
|
|
113
113
|
};
|
|
114
|
-
|
|
114
|
+
direction: ConvexTextBuilderInitial<""> & {
|
|
115
115
|
_: {
|
|
116
116
|
tableName: "migration_state";
|
|
117
117
|
};
|
|
118
118
|
} & {
|
|
119
119
|
_: {
|
|
120
|
-
fieldName: "
|
|
120
|
+
fieldName: "direction";
|
|
121
121
|
};
|
|
122
122
|
};
|
|
123
123
|
migrationId: ConvexTextBuilderInitial<""> & {
|
|
@@ -1326,11 +1326,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1326
1326
|
readonly aggregate_extrema: ConvexTableWithColumns<{
|
|
1327
1327
|
name: "aggregate_extrema";
|
|
1328
1328
|
columns: {
|
|
1329
|
-
|
|
1330
|
-
_: {
|
|
1331
|
-
$type: convex_values0.Value;
|
|
1332
|
-
};
|
|
1333
|
-
} & {
|
|
1329
|
+
count: ConvexNumberBuilderInitial<""> & {
|
|
1334
1330
|
_: {
|
|
1335
1331
|
notNull: true;
|
|
1336
1332
|
};
|
|
@@ -1340,10 +1336,14 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1340
1336
|
};
|
|
1341
1337
|
} & {
|
|
1342
1338
|
_: {
|
|
1343
|
-
fieldName: "
|
|
1339
|
+
fieldName: "count";
|
|
1344
1340
|
};
|
|
1345
1341
|
};
|
|
1346
|
-
|
|
1342
|
+
value: ConvexCustomBuilderInitial<"", convex_values0.VAny<any, "required", string>> & {
|
|
1343
|
+
_: {
|
|
1344
|
+
$type: convex_values0.Value;
|
|
1345
|
+
};
|
|
1346
|
+
} & {
|
|
1347
1347
|
_: {
|
|
1348
1348
|
notNull: true;
|
|
1349
1349
|
};
|
|
@@ -1353,7 +1353,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1353
1353
|
};
|
|
1354
1354
|
} & {
|
|
1355
1355
|
_: {
|
|
1356
|
-
fieldName: "
|
|
1356
|
+
fieldName: "value";
|
|
1357
1357
|
};
|
|
1358
1358
|
};
|
|
1359
1359
|
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
@@ -1596,26 +1596,26 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1596
1596
|
fieldName: "status";
|
|
1597
1597
|
};
|
|
1598
1598
|
};
|
|
1599
|
-
|
|
1600
|
-
_: {
|
|
1601
|
-
notNull: true;
|
|
1602
|
-
};
|
|
1603
|
-
} & {
|
|
1599
|
+
cursor: ConvexTextBuilderInitial<""> & {
|
|
1604
1600
|
_: {
|
|
1605
1601
|
tableName: "aggregate_state";
|
|
1606
1602
|
};
|
|
1607
1603
|
} & {
|
|
1608
1604
|
_: {
|
|
1609
|
-
fieldName: "
|
|
1605
|
+
fieldName: "cursor";
|
|
1610
1606
|
};
|
|
1611
1607
|
};
|
|
1612
|
-
|
|
1608
|
+
kind: ConvexTextBuilderInitial<""> & {
|
|
1609
|
+
_: {
|
|
1610
|
+
notNull: true;
|
|
1611
|
+
};
|
|
1612
|
+
} & {
|
|
1613
1613
|
_: {
|
|
1614
1614
|
tableName: "aggregate_state";
|
|
1615
1615
|
};
|
|
1616
1616
|
} & {
|
|
1617
1617
|
_: {
|
|
1618
|
-
fieldName: "
|
|
1618
|
+
fieldName: "kind";
|
|
1619
1619
|
};
|
|
1620
1620
|
};
|
|
1621
1621
|
processed: ConvexNumberBuilderInitial<""> & {
|
|
@@ -1751,22 +1751,22 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1751
1751
|
fieldName: "status";
|
|
1752
1752
|
};
|
|
1753
1753
|
};
|
|
1754
|
-
|
|
1754
|
+
cursor: ConvexTextBuilderInitial<""> & {
|
|
1755
1755
|
_: {
|
|
1756
1756
|
tableName: "migration_state";
|
|
1757
1757
|
};
|
|
1758
1758
|
} & {
|
|
1759
1759
|
_: {
|
|
1760
|
-
fieldName: "
|
|
1760
|
+
fieldName: "cursor";
|
|
1761
1761
|
};
|
|
1762
1762
|
};
|
|
1763
|
-
|
|
1763
|
+
direction: ConvexTextBuilderInitial<""> & {
|
|
1764
1764
|
_: {
|
|
1765
1765
|
tableName: "migration_state";
|
|
1766
1766
|
};
|
|
1767
1767
|
} & {
|
|
1768
1768
|
_: {
|
|
1769
|
-
fieldName: "
|
|
1769
|
+
fieldName: "direction";
|
|
1770
1770
|
};
|
|
1771
1771
|
};
|
|
1772
1772
|
migrationId: ConvexTextBuilderInitial<""> & {
|
package/package.json
CHANGED
|
@@ -363,7 +363,7 @@ All from `kitcn/react`:
|
|
|
363
363
|
|------|---------|-------------|
|
|
364
364
|
| `useAuth()` | `{ hasSession, isAuthenticated, isLoading }` | Full auth state |
|
|
365
365
|
| `useMaybeAuth()` | `boolean` | Has token (optimistic, may not be verified) |
|
|
366
|
-
| `useIsAuth()` | `boolean` | Server-verified authentication |
|
|
366
|
+
| `useIsAuth()` | `boolean` | Server-verified authentication (with `optimisticAuth`, also during the optimistic window) |
|
|
367
367
|
| `useAuthGuard()` | `() => boolean` | Guard mutations, returns true if blocked |
|
|
368
368
|
| `useConvexAuthRecovery()` | `{ recover, status, error }` | Rebind Convex auth after a transient token failure |
|
|
369
369
|
|
|
@@ -389,7 +389,7 @@ All from `kitcn/react`:
|
|
|
389
389
|
| Component | Renders when |
|
|
390
390
|
|-----------|-------------|
|
|
391
391
|
| `MaybeAuthenticated` | Has session token (optimistic) |
|
|
392
|
-
| `Authenticated` | Server-verified authenticated |
|
|
392
|
+
| `Authenticated` | Server-verified authenticated (with `optimisticAuth`, also during the optimistic window) |
|
|
393
393
|
| `MaybeUnauthenticated` | No session token (optimistic) |
|
|
394
394
|
| `Unauthenticated` | Server-verified not authenticated |
|
|
395
395
|
|
|
@@ -414,16 +414,34 @@ All from `kitcn/react`:
|
|
|
414
414
|
```
|
|
415
415
|
|
|
416
416
|
`optimisticAuth` only opens auth-bound query gates for a held, unexpired JWT;
|
|
417
|
-
expired, opaque, and refused tokens stay closed.
|
|
417
|
+
expired, opaque, and refused tokens stay closed. The window ends at the Convex
|
|
418
|
+
client's first auth result; use one `optimisticAuth` setting per client; no
|
|
419
|
+
optimism over a client the Start loader authenticated. Enable
|
|
418
420
|
`onTokenIdentityChange` to refuse a JWT whose `sub` or `sessionId` differs from
|
|
419
|
-
the document identity before Convex
|
|
420
|
-
|
|
421
|
+
the document identity (whatever its `exp`) before Convex, HTTP or the Start
|
|
422
|
+
loader sees it. On a trip, every mounted provider hands out no token and
|
|
423
|
+
publishes unauthenticated; each guarded one closes its client, then calls the
|
|
424
|
+
callback once, so reload the document there. Browser only, page-wide: later
|
|
425
|
+
providers start tripped, and a guarded one that mounts or shows again on a
|
|
426
|
+
tripped page also closes its client and calls the callback once. Enabling the
|
|
427
|
+
guard on a tripped page delivers that close and callback once too; sign-in
|
|
428
|
+
mutations fail with `TOKEN_IDENTITY_CHANGED`.
|
|
421
429
|
|
|
422
430
|
For multiple provider mounts, pass `tokenIdentityBaseline` as
|
|
423
|
-
`sub|sessionId`, or a getter returning the document's current identity.
|
|
424
|
-
|
|
431
|
+
`sub|sessionId`, or a getter returning the document's current identity. Every
|
|
432
|
+
admission (SSR, fresh and cached tokens, sign-in, HTTP, Start loader) binds a
|
|
433
|
+
token to the page identity, the provider's own baseline and every mounted
|
|
434
|
+
provider's current getter answer; an opaque session token is only exchanged,
|
|
435
|
+
never handed to Convex. Held tokens are reconciled when a provider joins the
|
|
436
|
+
page and at every admission. A page that never enables the guard is
|
|
437
|
+
unchanged; once a guarded provider establishes the page identity it persists
|
|
438
|
+
until reload, binding every provider and the Start loader, even after that
|
|
439
|
+
provider unmounts. Two kitcn versions or revisions on one page (dev HMR
|
|
440
|
+
across revisions included) are unsupported: no shared page identity until
|
|
441
|
+
reload.
|
|
425
442
|
`onTokenIdentityAdmitted(token)` observes admitted JWTs so the app can update
|
|
426
|
-
that shared baseline.
|
|
443
|
+
that shared baseline. Admission rechecks the baseline after the callback before
|
|
444
|
+
publishing or handing out the token. All three identity options require
|
|
427
445
|
`onTokenIdentityChange`.
|
|
428
446
|
|
|
429
447
|
For `@convex-dev/auth` (React Native):
|
|
@@ -539,7 +539,11 @@ export const { createContext, createCaller, handler } = convexBetterAuth({
|
|
|
539
539
|
| `createCaller` | Server-side caller factory |
|
|
540
540
|
| `handler` | Next.js API route handler (`export const { GET, POST, OPTIONS } = handler;`) |
|
|
541
541
|
|
|
542
|
-
Options: `api`, `convexSiteUrl`, `auth.jwtCache` (default true),
|
|
542
|
+
Options: `api`, `convexSiteUrl`, `auth.jwtCache` (boolean or `{ now }`, default true),
|
|
543
|
+
`auth.expirationToleranceSeconds` (default 60), `auth.isUnauthorized`.
|
|
544
|
+
`now` returns finite Unix seconds or a promise of seconds. For Next partial
|
|
545
|
+
prefetching and request-time versus private-cache clocks, follow
|
|
546
|
+
[Next setup](../setup/next.md#8a4-jwt-cache-and-partial-prefetching).
|
|
543
547
|
|
|
544
548
|
### Client Provider with Auth
|
|
545
549
|
|
|
@@ -98,7 +98,54 @@ export function HydrateClient({ children }: { children: React.ReactNode }) {
|
|
|
98
98
|
}
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
### 8.A.4
|
|
101
|
+
### 8.A.4 JWT cache and partial prefetching
|
|
102
|
+
|
|
103
|
+
With Next 16 `cacheComponents` and `partialPrefetching`, the default JWT expiry
|
|
104
|
+
clock can trigger a Blocking Route error even after `await headers()`. The
|
|
105
|
+
app owns clock timing. For request-time contexts, configure the server factory:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { connection } from 'next/server';
|
|
109
|
+
|
|
110
|
+
export const { createContext, createCaller, handler } = convexBetterAuth({
|
|
111
|
+
api,
|
|
112
|
+
convexSiteUrl: process.env.NEXT_PUBLIC_CONVEX_SITE_URL!,
|
|
113
|
+
auth: {
|
|
114
|
+
jwtCache: {
|
|
115
|
+
now: async () => {
|
|
116
|
+
await connection();
|
|
117
|
+
return Math.floor(Date.now() / 1000);
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`auth.jwtCache` accepts a boolean or `{ now?: () => number | Promise<number> }`.
|
|
125
|
+
The clock returns finite **Unix seconds**, not milliseconds. The reader awaits
|
|
126
|
+
it only for a decoded cached JWT with an expiry. Disabled caching, forced
|
|
127
|
+
refresh, missing/malformed cookies, and absent expiry bypass the hook.
|
|
128
|
+
`auth.expirationToleranceSeconds` remains a sibling option (default 60).
|
|
129
|
+
Clock throws/rejections propagate unchanged; `NaN` and infinities are rejected.
|
|
130
|
+
|
|
131
|
+
Keep `await headers()` in the RSC context creator. Put request-time token reads
|
|
132
|
+
under `Suspense`, including a provider or route gate that awaits `caller.getToken()`.
|
|
133
|
+
For `'use cache: private'`, use a separate factory with the default or a sync
|
|
134
|
+
clock; **never call `connection()` inside private cache**. A private token helper
|
|
135
|
+
can use `cacheLife({ stale: 30 })`, read headers, create that context, and return
|
|
136
|
+
`context.token`. A token-blocking layout must defer its token-dependent subtree
|
|
137
|
+
with `Suspense`, including when awaiting a private-cache helper. Private caching
|
|
138
|
+
allows the clock read but does not make runtime auth data static.
|
|
139
|
+
|
|
140
|
+
`auth: { jwtCache: false }` avoids the cookie expiry clock but fetches a token
|
|
141
|
+
on every context creation. Kitcn does not import Next, detect render stages, or
|
|
142
|
+
suppress render aborts. An app that runs a `connection()` clock through TanStack
|
|
143
|
+
queries owns abort handling because recording a query failure can also read
|
|
144
|
+
`Date.now()`. Do not suppress ordinary auth failures.
|
|
145
|
+
|
|
146
|
+
Full examples: [Next.js JWT cache guidance](https://kitcn.dev/docs/nextjs#jwt-cache-and-partial-prefetching).
|
|
147
|
+
|
|
148
|
+
### 8.A.5 Pass server token to provider
|
|
102
149
|
|
|
103
150
|
```tsx
|
|
104
151
|
// app/(app)/layout.tsx
|