@swimmesberger/elarion-jsonrpc-client-generator 0.2.11 → 0.2.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
@@ -125,14 +125,22 @@ The core client stays framework-neutral, but you can opt into a framework adapte
125
125
  npx elarion-jsonrpc-client-generator --schema rpc-schema.json --out src/generated --framework tanstack-start
126
126
  ```
127
127
 
128
- It exports `createStartRpcApi` — a `createRpcApi` with request-scoped cookie forwarding pre-wired for SSR — and
129
- `forwardRequestCookie`, the isomorphic headers function on its own. The core client never imports the adapter, so
130
- consumers that don't opt in stay framework-neutral and their output is byte-identical.
128
+ It exports `createStartRpcApi` — a `createRpcApi` with request-scoped header forwarding pre-wired for SSR (the
129
+ `cookie` by default) — plus the isomorphic headers functions on their own: `forwardRequestHeaders(names)` and
130
+ `forwardRequestCookie`. The core client never imports the adapter, so consumers that don't opt in stay
131
+ framework-neutral and their output is byte-identical.
131
132
 
132
133
  ```ts
133
134
  import { createStartRpcApi } from './generated/start-adapter'
134
135
 
135
136
  export const rpc = createStartRpcApi({ url: '/rpc' })
137
+
138
+ // Behind an authenticating reverse proxy, forward its identity header too. The list replaces the default,
139
+ // so keep 'cookie' in it when the session cookie should still travel.
140
+ export const proxiedRpc = createStartRpcApi({
141
+ url: '/rpc',
142
+ forwardHeaders: ['cookie', 'cf-access-jwt-assertion'], // e.g. Cloudflare Access
143
+ })
136
144
  ```
137
145
 
138
146
  ## Client-side tracing
@@ -6,7 +6,9 @@ export interface GenerateStartAdapterSourceOptions {
6
6
  }
7
7
  /**
8
8
  * Emits the opt-in TanStack Start adapter (`start-adapter.ts`), produced only with `--framework tanstack-start`.
9
- * It imports the framework-specific pieces (`@tanstack/react-start`) so the core generated client never does —
10
- * a non-Start consumer neither installs nor imports this file, keeping the client's framework-neutral boundary.
9
+ * It forwards incoming request headers (the `cookie` by default, or the configured `forwardHeaders`) to API calls
10
+ * made during SSR. It imports the framework-specific pieces (`@tanstack/react-start`) so the core generated client
11
+ * never does — a non-Start consumer neither installs nor imports this file, keeping the client's framework-neutral
12
+ * boundary.
11
13
  */
12
14
  export declare function generateStartAdapterSource(options: GenerateStartAdapterSourceOptions): string;
@@ -1,8 +1,10 @@
1
1
  import { moduleSpecifier } from './rpc-client-source.js';
2
2
  /**
3
3
  * Emits the opt-in TanStack Start adapter (`start-adapter.ts`), produced only with `--framework tanstack-start`.
4
- * It imports the framework-specific pieces (`@tanstack/react-start`) so the core generated client never does —
5
- * a non-Start consumer neither installs nor imports this file, keeping the client's framework-neutral boundary.
4
+ * It forwards incoming request headers (the `cookie` by default, or the configured `forwardHeaders`) to API calls
5
+ * made during SSR. It imports the framework-specific pieces (`@tanstack/react-start`) so the core generated client
6
+ * never does — a non-Start consumer neither installs nor imports this file, keeping the client's framework-neutral
7
+ * boundary.
6
8
  */
7
9
  export function generateStartAdapterSource(options) {
8
10
  const clientImport = moduleSpecifier(options.clientFileName);
@@ -17,29 +19,49 @@ export function generateStartAdapterSource(options) {
17
19
  "import { getRequestHeader } from '@tanstack/react-start/server'",
18
20
  `import { createRpcApi, type RpcApi, type RpcClientOptions, type RpcHeadersInit } from '${clientImport}'`,
19
21
  '',
20
- "// Forwards the incoming request's `cookie` during SSR so the RPC call runs as the signed-in user, and",
21
- '// returns nothing in the browser. The read is isolated inside `createIsomorphicFn().server(...)` so the',
22
- '// TanStack Start compiler strips both the read and the `@tanstack/react-start/server` import from the',
23
- '// client bundle — a plain import (even one behind a `typeof window` guard) would fail `vite build` with',
24
- '// `[import-protection] Import denied`.',
25
- 'export const forwardRequestCookie = createIsomorphicFn()',
26
- ' .server((): RpcHeadersInit => {',
27
- " const cookie = getRequestHeader('cookie')",
28
- ' return cookie ? { cookie } : {}',
22
+ "// Forwards the named headers of the incoming request during SSR (names are matched case-insensitively and",
23
+ "// emitted lower-case; a header the request does not carry is skipped), and returns nothing in the browser.",
24
+ "// The read is isolated inside `createIsomorphicFn().server(...)` so the TanStack Start compiler strips both",
25
+ "// the read and the `@tanstack/react-start/server` import from the client bundle — a plain import (even one",
26
+ "// behind a `typeof window` guard) would fail `vite build` with `[import-protection] Import denied`.",
27
+ 'export const forwardRequestHeaders = createIsomorphicFn()',
28
+ ' .server((names: readonly string[]): RpcHeadersInit => {',
29
+ ' const forwarded: Record<string, string> = {}',
30
+ ' for (const name of names) {',
31
+ ' const value = getRequestHeader(name)',
32
+ ' if (value) {',
33
+ ' forwarded[name.toLowerCase()] = value',
34
+ ' }',
35
+ ' }',
36
+ ' return forwarded',
29
37
  ' })',
30
- ' .client((): RpcHeadersInit => ({}))',
38
+ ' .client((_names: readonly string[]): RpcHeadersInit => ({}))',
39
+ '',
40
+ "// Forwards the incoming request's `cookie` during SSR so the RPC call runs as the signed-in user.",
41
+ "export const forwardRequestCookie = (): RpcHeadersInit => forwardRequestHeaders(['cookie'])",
42
+ '',
43
+ '/** Options for {@link createStartRpcApi}: the core client options plus the request headers forwarded during SSR. */',
44
+ 'export interface StartRpcClientOptions extends RpcClientOptions {',
45
+ ' /**',
46
+ " * Incoming request headers to forward on every call made during SSR (default `['cookie']`). The list",
47
+ " * replaces the default, so include `'cookie'` when you still want the session cookie forwarded; an empty",
48
+ ' * list forwards nothing. Forward identity or correlation headers only — never hop-by-hop or',
49
+ ' * framing headers such as `host`, `connection`, or `content-length`.',
50
+ ' */',
51
+ ' readonly forwardHeaders?: readonly string[]',
52
+ '}',
31
53
  '',
32
- '// Turnkey `createRpcApi` for a TanStack Start app: request-scoped cookie forwarding is pre-wired, and any',
33
- '// `headers` you pass are layered on top (yours win on a conflict). Everything else in RpcClientOptions',
34
- '// (url, fetch, idempotency, instrumentation, …) passes through unchanged.',
35
- 'export function createStartRpcApi(options: RpcClientOptions): RpcApi {',
36
- ' const provided = options.headers',
54
+ '// Turnkey `createRpcApi` for a TanStack Start app: request-scoped header forwarding (the `cookie` by',
55
+ '// default) is pre-wired, and any `headers` you pass are layered on top (yours win on a conflict).',
56
+ '// Everything else in RpcClientOptions (url, fetch, idempotency, instrumentation, …) passes through unchanged.',
57
+ 'export function createStartRpcApi(options: StartRpcClientOptions): RpcApi {',
58
+ " const { forwardHeaders = ['cookie'], headers: provided, ...rest } = options",
37
59
  ' return createRpcApi({',
38
- ' ...options,',
60
+ ' ...rest,',
39
61
  ' headers: async (context) => {',
40
- ' const cookie = await forwardRequestCookie()',
62
+ ' const forwarded = await forwardRequestHeaders(forwardHeaders)',
41
63
  " const extra = typeof provided === 'function' ? await provided(context) : provided",
42
- ' return { ...toHeaderRecord(cookie), ...toHeaderRecord(extra) }',
64
+ ' return { ...toHeaderRecord(forwarded), ...toHeaderRecord(extra) }',
43
65
  ' },',
44
66
  ' })',
45
67
  '}',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swimmesberger/elarion-jsonrpc-client-generator",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "Generate TypeScript RPC contracts, Zod schemas, and a fetch client from Elarion JSON-RPC schema exports.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",