@aventara/next 1.0.0-rc.12 → 1.0.0-rc.13

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 CHANGED
@@ -1,5 +1,42 @@
1
1
  # @aventara/next
2
2
 
3
+ ## 1.0.0-rc.13
4
+
5
+ ### Patch Changes
6
+
7
+ - e4e8abd: The same rule now holds for in-process calls. When `state` rejects with an object whose `status` or `statusCode` is
8
+ the number 401 or 403, an `avClient` call in a Next.js Server Component or Server Action rejects with an `AvAuthError`
9
+ of code `A4000` or `A4001`, and so does `framework.serverClient.$access.can` given `headers`. Its message is core's own
10
+ (`"Unauthenticated."` or `"Forbidden."`) and nothing of the rejection reaches the caller. Before, the call rejected
11
+ with the library's own error. A thrown `AvError` and any other rejection still reject the call unchanged.
12
+
13
+ An object whose `status` and `statusCode` are both numbers that disagree, such as `status: 500` beside
14
+ `statusCode: 401`, is no longer read as a refusal: a route answers it `500 A3000`. A number beside a non-number, such
15
+ as Better Auth's `status: "UNAUTHORIZED"` beside `statusCode: 401`, is still read by the number.
16
+
17
+ - e662048: A request whose `state` (the host's `state` option, or the `access` provider's `state`) rejects with an object whose
18
+ `status` or `statusCode` is the number 401 or 403 is now answered `401 A4000` or `403 A4001`, not `500 A3000`. This is
19
+ how authentication libraries refuse a bad credential: Better Auth's `APIError` for a wrong API key carries
20
+ `statusCode: 401`. The answer is core's own envelope (`"Unauthenticated."` or `"Forbidden."`); nothing of the
21
+ rejection, neither its message nor its code, reaches the caller, and it is not reported to `diagnostics`, as a thrown
22
+ `AvError("A4000", …)` is not. It applies on every protocol route that seeds state: operations, cached reads,
23
+ `/_transactions`, `/_all`, `/_access/can`, and MCP tool calls. A thrown `AvError` is still its own outcome, and any
24
+ other rejection, a 401 beside a 403 included, is still `500 A3000`.
25
+ - Updated dependencies [6c3e25c]
26
+ - Updated dependencies [2aaa27d]
27
+ - Updated dependencies [f3b291f]
28
+ - Updated dependencies [2aaa27d]
29
+ - Updated dependencies [e4e8abd]
30
+ - Updated dependencies [e662048]
31
+ - Updated dependencies [f3b291f]
32
+ - Updated dependencies [f3b291f]
33
+ - Updated dependencies [6c3e25c]
34
+ - Updated dependencies [6c3e25c]
35
+ - Updated dependencies [a708188]
36
+ - Updated dependencies [a9260d2]
37
+ - @aventara/core@1.0.0-rc.13
38
+ - @aventara/mcp@1.0.0-rc.13
39
+
3
40
  ## 1.0.0-rc.12
4
41
 
5
42
  ### Patch Changes
package/README.md CHANGED
@@ -287,6 +287,17 @@ With SWR, pass `avDehydrate({ [key]: data })` from the Server Component and `avH
287
287
  Importing `@/aventara/client` instead of `@/aventara/universal` in shared code opts out of running on the server: its
288
288
  calls are refused there.
289
289
 
290
+ ### The client's hooks
291
+
292
+ `onCall`, `onSuccess` and `onError` for `@/aventara/client` and `@/aventara/universal` go in
293
+ `src/aventara/client-options.ts` (or `.js`), whose default export `aventara-build --client` gives every client it writes
294
+ (`@aventara/build`'s README). The file ships to the browser too: no server-only import, no secret, and
295
+ `typeof window` when a hook must act differently on the server. On the server, `onCall`'s headers reach the in-process
296
+ request but not its state, which comes from the request being served. `@/aventara/server` is the Framework's own
297
+ client, not an `AvClient`, and takes no hooks. Calls group in the browser only when their `onCall` settles together
298
+ with equal additions: an `onCall` reading a token over I/O for each call sends each call alone, so read it through
299
+ one shared in-flight promise, cleared once it settles (`@aventara/client`'s README has the recipe).
300
+
290
301
  ## Routes
291
302
 
292
303
  `handlers` answers the protocol's routes under `api`: each operation route (`POST /api/_resources/...`),
@@ -12,10 +12,15 @@ type HostOptions<M extends AvAdapterModel> = {
12
12
  readonly adapter: AvAdapter<M> | (() => AvAdapter<M> | PromiseLike<AvAdapter<M>>);
13
13
  /**
14
14
  * Seeds a request's `ctx.$state`, once per request, from its headers and,
15
- * on a route call, the route handler's request. A throw is answered like
16
- * any developer failure: a thrown `AvError` as its own outcome, anything
17
- * else as an internal failure. Omitted, the state is `{}`, or what the
18
- * `access` provider's `state` seeds; not together with `access`.
15
+ * on a route call, the route handler's request. A thrown `AvError` is its
16
+ * own outcome. A rejection carrying `status` or `statusCode` 401 or 403
17
+ * (two numbers that disagree are neither) is `A4000` or `A4001`, with
18
+ * core's own message and nothing of the rejection's, unreported: a route
19
+ * answers `401` or `403`, and an `avClient` call in a Server Component or
20
+ * Server Action rejects with that code's `AvAuthError`. Anything else is
21
+ * `500 A3000` on a route, and rejects an `avClient` call unchanged.
22
+ * Omitted, the state is `{}`, or what the `access` provider's `state`
23
+ * seeds; not together with `access`.
19
24
  */
20
25
  state?(context: AvNextStateContext): AvState | Promise<AvState>;
21
26
  };
@@ -1,4 +1,4 @@
1
- import { holdRequestPrincipal } from "@aventara/core/internal";
1
+ import { holdRequestPrincipal, inProcessStateRejection, } from "@aventara/core/internal";
2
2
  import { headers } from "next/headers.js";
3
3
  import { cache } from "react";
4
4
  export function createRequestState(state) {
@@ -6,7 +6,14 @@ export function createRequestState(state) {
6
6
  return async () => undefined;
7
7
  }
8
8
  return cache(async () => {
9
- const seeded = await state({ headers: await headers() });
9
+ const given = await headers();
10
+ let seeded;
11
+ try {
12
+ seeded = await state({ headers: given });
13
+ }
14
+ catch (error) {
15
+ throw inProcessStateRejection(error);
16
+ }
10
17
  holdRequestPrincipal(seeded);
11
18
  return seeded;
12
19
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aventara/next",
3
- "version": "1.0.0-rc.12",
3
+ "version": "1.0.0-rc.13",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "Next.js App Router host integration for Aventara.",
6
6
  "type": "module",
@@ -22,11 +22,11 @@
22
22
  "CHANGELOG.md"
23
23
  ],
24
24
  "dependencies": {
25
- "@aventara/core": "1.0.0-rc.12",
25
+ "@aventara/core": "1.0.0-rc.13",
26
26
  "server-only": "0.0.1"
27
27
  },
28
28
  "peerDependencies": {
29
- "@aventara/mcp": "1.0.0-rc.12",
29
+ "@aventara/mcp": "1.0.0-rc.13",
30
30
  "next": ">=16.4 <17",
31
31
  "react": "^19.0.0"
32
32
  },
@@ -53,10 +53,10 @@
53
53
  "access": "public"
54
54
  },
55
55
  "devDependencies": {
56
- "@aventara/build": "1.0.0-rc.12",
57
- "@aventara/client": "1.0.0-rc.12",
58
- "@aventara/mcp": "1.0.0-rc.12",
59
- "@aventara/testing": "1.0.0-rc.12",
56
+ "@aventara/build": "1.0.0-rc.13",
57
+ "@aventara/client": "1.0.0-rc.13",
58
+ "@aventara/mcp": "1.0.0-rc.13",
59
+ "@aventara/testing": "1.0.0-rc.13",
60
60
  "@modelcontextprotocol/sdk": "1.32.2",
61
61
  "@tanstack/react-query": "5.104.2",
62
62
  "@types/react": "19.3.0",