@tanstack-router-testing/react-start-testing 0.0.1 → 0.1.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.
- package/dist/browser.d.mts +2 -0
- package/dist/browser.mjs +2 -0
- package/dist/index.d.mts +2 -163
- package/dist/index.mjs +3 -146
- package/dist/index.mjs.map +1 -1
- package/dist/isomorphic-Bw5L_zk1.mjs +148 -0
- package/dist/isomorphic-Bw5L_zk1.mjs.map +1 -0
- package/dist/isomorphic-DiwceaLg.d.mts +166 -0
- package/dist/{shim-DR16QaLL.mjs → shim-C-PA0sYH.mjs} +1 -1
- package/dist/{shim-DR16QaLL.mjs.map → shim-C-PA0sYH.mjs.map} +1 -1
- package/dist/shim.mjs +1 -1
- package/dist/vite.d.mts +23 -1
- package/dist/vite.mjs +60 -5
- package/dist/vite.mjs.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as ServerFnMock, i as AnyServerFn, n as MockMiddlewareOptions, o as mockServerFn, r as mockMiddleware, s as clearStartMocks, t as runInStartEnv } from "./isomorphic-DiwceaLg.mjs";
|
|
2
|
+
export { type AnyServerFn, type MockMiddlewareOptions, type ServerFnMock, clearStartMocks, mockMiddleware, mockServerFn, runInStartEnv };
|
package/dist/browser.mjs
ADDED
package/dist/index.d.mts
CHANGED
|
@@ -1,171 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as ServerFnMock, i as AnyServerFn, n as MockMiddlewareOptions, o as mockServerFn, r as mockMiddleware, s as clearStartMocks, t as runInStartEnv } from "./isomorphic-DiwceaLg.mjs";
|
|
2
|
+
import { CallMiddlewareOptions, CallMiddlewareResult, TestEnv, callMiddleware } from "@tanstack-router-testing/router-testing-core";
|
|
2
3
|
import { ComponentType } from "react";
|
|
3
4
|
import { StartHandlerType } from "@tanstack/start-storage-context";
|
|
4
5
|
import { AnyRouter } from "@tanstack/react-router";
|
|
5
6
|
import { AnyStartInstanceOptions } from "@tanstack/start-client-core";
|
|
6
7
|
|
|
7
|
-
//#region src/clearStartMocks.d.ts
|
|
8
|
-
/**
|
|
9
|
-
* Clear every server-function and middleware mock installed by
|
|
10
|
-
* {@link mockServerFn} or {@link mockMiddleware}.
|
|
11
|
-
*
|
|
12
|
-
* @returns `void`.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* import { afterEach } from 'vitest';
|
|
17
|
-
* import { clearStartMocks } from '@tanstack-router-testing/react-start-testing';
|
|
18
|
-
*
|
|
19
|
-
* afterEach(() => {
|
|
20
|
-
* clearStartMocks();
|
|
21
|
-
* });
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* This is the same function wired to {@link StartTestRuntime.cleanup}, so you
|
|
26
|
-
* only need to call it explicitly when installing mocks outside of a runtime
|
|
27
|
-
* (i.e. via {@link mockServerFn} / {@link mockMiddleware} directly).
|
|
28
|
-
*/
|
|
29
|
-
declare const clearStartMocks: () => void;
|
|
30
|
-
//#endregion
|
|
31
|
-
//#region src/mockServerFn.d.ts
|
|
32
|
-
/**
|
|
33
|
-
* Catch-all type representing any TanStack Start server function.
|
|
34
|
-
*
|
|
35
|
-
* @remarks
|
|
36
|
-
* Used as a generic constraint in {@link mockServerFn} and {@link ServerFnMock}
|
|
37
|
-
* to accept any function created by `createServerFn().handler(...)`.
|
|
38
|
-
*/
|
|
39
|
-
type AnyServerFn = (...args: never[]) => unknown;
|
|
40
|
-
/**
|
|
41
|
-
* The mock implementation signature for a server function of type `TFn`.
|
|
42
|
-
*
|
|
43
|
-
* @typeParam TFn - The server function type being mocked.
|
|
44
|
-
*
|
|
45
|
-
* @remarks
|
|
46
|
-
* The mock receives the same callable-shape arguments as the real server
|
|
47
|
-
* function (e.g. `{ data }`) and must return a compatible result. Full generic
|
|
48
|
-
* inference is preserved so autocomplete works identically to the real call.
|
|
49
|
-
*
|
|
50
|
-
* @see {@link mockServerFn}
|
|
51
|
-
*/
|
|
52
|
-
type ServerFnMock<TFn extends AnyServerFn> = (...args: Parameters<TFn>) => ReturnType<TFn>;
|
|
53
|
-
/**
|
|
54
|
-
* Install a mock implementation for a TanStack Start server function.
|
|
55
|
-
*
|
|
56
|
-
* @param fn - The server function created by `createServerFn().handler(...)`.
|
|
57
|
-
* @param impl - A {@link ServerFnMock} that replaces the real handler for the
|
|
58
|
-
* duration of the test. It receives the same callable-shape arguments (e.g.
|
|
59
|
-
* `{ data }`) as the original function.
|
|
60
|
-
* @returns A disposer function that restores the original implementation when
|
|
61
|
-
* called. Alternatively, call {@link clearStartMocks} to remove all mocks at
|
|
62
|
-
* once.
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```ts
|
|
66
|
-
* import { createServerFn } from '@tanstack/react-start';
|
|
67
|
-
* import { mockServerFn } from '@tanstack-router-testing/react-start-testing';
|
|
68
|
-
*
|
|
69
|
-
* const listOrders = createServerFn()
|
|
70
|
-
* .validator((input: { userId: string }) => input)
|
|
71
|
-
* .handler(async ({ data }) => db.orders.findMany(data.userId));
|
|
72
|
-
*
|
|
73
|
-
* const dispose = mockServerFn(listOrders, async ({ data }) => [
|
|
74
|
-
* { id: '1', userId: data.userId, total: 42 },
|
|
75
|
-
* ]);
|
|
76
|
-
*
|
|
77
|
-
* // ... run your test ...
|
|
78
|
-
* dispose();
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* @remarks
|
|
82
|
-
* The mock is authored against the public callable shape, so a server function
|
|
83
|
-
* normally called as `listOrders({ data })` is mocked with that same signature.
|
|
84
|
-
* Internal context fields are normalised automatically before reaching the mock.
|
|
85
|
-
*/
|
|
86
|
-
declare const mockServerFn: <TFn extends AnyServerFn>(fn: TFn, impl: ServerFnMock<TFn>) => (() => void);
|
|
87
|
-
//#endregion
|
|
88
|
-
//#region src/mockMiddleware.d.ts
|
|
89
|
-
/**
|
|
90
|
-
* Phase override options for {@link mockMiddleware}.
|
|
91
|
-
*
|
|
92
|
-
* @remarks
|
|
93
|
-
* Provide `client`, `server`, or both. Omitted keys leave the corresponding
|
|
94
|
-
* phase untouched, so you can mock only the server side without affecting the
|
|
95
|
-
* client phase and vice-versa.
|
|
96
|
-
*/
|
|
97
|
-
interface MockMiddlewareOptions {
|
|
98
|
-
/** Override for the `.client()` phase. When omitted the real client handler runs. */
|
|
99
|
-
readonly client?: AnyFn;
|
|
100
|
-
/** Override for the `.server()` phase. When omitted the real server handler runs. */
|
|
101
|
-
readonly server?: AnyFn;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Override one or both phases of a registered middleware.
|
|
105
|
-
*
|
|
106
|
-
* @param mw - The middleware object returned by
|
|
107
|
-
* `createMiddleware().server(...).client(...)`.
|
|
108
|
-
* @param options - A {@link MockMiddlewareOptions} object specifying which
|
|
109
|
-
* phases to replace.
|
|
110
|
-
* @returns A disposer function that restores the original middleware handlers.
|
|
111
|
-
* Alternatively, call {@link clearStartMocks} to remove all mocks at once.
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```ts
|
|
115
|
-
* import { createMiddleware } from '@tanstack/react-start';
|
|
116
|
-
* import { mockMiddleware } from '@tanstack-router-testing/react-start-testing';
|
|
117
|
-
*
|
|
118
|
-
* const authMiddleware = createMiddleware()
|
|
119
|
-
* .server(async ({ next }) => next({ context: { user: await getUser() } }))
|
|
120
|
-
* .client(async ({ next }) => next());
|
|
121
|
-
*
|
|
122
|
-
* const dispose = mockMiddleware(authMiddleware, {
|
|
123
|
-
* server: async ({ next }) => next({ context: { user: { id: 'test-user' } } }),
|
|
124
|
-
* });
|
|
125
|
-
*
|
|
126
|
-
* // ... run your test ...
|
|
127
|
-
* dispose();
|
|
128
|
-
* ```
|
|
129
|
-
*
|
|
130
|
-
* @throws If `mw` is not registered. Registration is the shim's
|
|
131
|
-
* responsibility (see ADR 0001).
|
|
132
|
-
*
|
|
133
|
-
* @remarks
|
|
134
|
-
* Server functions are invoked directly and mocked middleware participates in
|
|
135
|
-
* that normal call path. Only the phases you specify in `options` are replaced;
|
|
136
|
-
* the rest continue to run their real implementations.
|
|
137
|
-
*/
|
|
138
|
-
declare const mockMiddleware: (mw: object, options: MockMiddlewareOptions) => (() => void);
|
|
139
|
-
//#endregion
|
|
140
|
-
//#region src/isomorphic.d.ts
|
|
141
|
-
/**
|
|
142
|
-
* Execute `fn` with the simulated TanStack Start environment forced to `env`,
|
|
143
|
-
* then restore the prior value.
|
|
144
|
-
*
|
|
145
|
-
* @typeParam T - The return type of `fn`.
|
|
146
|
-
* @param env - The environment to simulate: `'server'` or `'client'`.
|
|
147
|
-
* @param fn - A synchronous or asynchronous function to run inside the
|
|
148
|
-
* simulated environment.
|
|
149
|
-
* @returns A `Promise` resolving to the return value of `fn`.
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* ```ts
|
|
153
|
-
* import { runInStartEnv } from '@tanstack-router-testing/react-start-testing';
|
|
154
|
-
*
|
|
155
|
-
* const result = await runInStartEnv('server', () => {
|
|
156
|
-
* // Code here sees `import.meta.env.SSR === true`
|
|
157
|
-
* return fetchDataOnServer();
|
|
158
|
-
* });
|
|
159
|
-
* ```
|
|
160
|
-
*
|
|
161
|
-
* @remarks
|
|
162
|
-
* The environment is scoped to the execution of `fn` and is restored
|
|
163
|
-
* automatically even if `fn` throws. Used internally by
|
|
164
|
-
* {@link createStartTestRuntime} to set the environment for each
|
|
165
|
-
* {@link StartTestRuntime.run | run} invocation.
|
|
166
|
-
*/
|
|
167
|
-
declare const runInStartEnv: <T>(env: TestEnv, fn: () => T | Promise<T>) => Promise<T>;
|
|
168
|
-
//#endregion
|
|
169
8
|
//#region src/runtime.d.ts
|
|
170
9
|
/**
|
|
171
10
|
* Configuration for {@link createStartTestRuntime}.
|
package/dist/index.mjs
CHANGED
|
@@ -1,152 +1,9 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
1
|
+
import { i as clearStartMocks, n as mockMiddleware, r as mockServerFn, t as runInStartEnv } from "./isomorphic-Bw5L_zk1.mjs";
|
|
2
|
+
import { t as __setStartOptionsForTesting } from "./shim-C-PA0sYH.mjs";
|
|
3
|
+
import { callMiddleware } from "@tanstack-router-testing/router-testing-core";
|
|
3
4
|
import { createElement } from "react";
|
|
4
5
|
import { renderToReadableStream, renderToString } from "react-dom/server";
|
|
5
6
|
import { runWithStartContext } from "@tanstack/start-storage-context";
|
|
6
|
-
//#region src/clearStartMocks.ts
|
|
7
|
-
/**
|
|
8
|
-
* Clear every server-function and middleware mock installed by
|
|
9
|
-
* {@link mockServerFn} or {@link mockMiddleware}.
|
|
10
|
-
*
|
|
11
|
-
* @returns `void`.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* import { afterEach } from 'vitest';
|
|
16
|
-
* import { clearStartMocks } from '@tanstack-router-testing/react-start-testing';
|
|
17
|
-
*
|
|
18
|
-
* afterEach(() => {
|
|
19
|
-
* clearStartMocks();
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* @remarks
|
|
24
|
-
* This is the same function wired to {@link StartTestRuntime.cleanup}, so you
|
|
25
|
-
* only need to call it explicitly when installing mocks outside of a runtime
|
|
26
|
-
* (i.e. via {@link mockServerFn} / {@link mockMiddleware} directly).
|
|
27
|
-
*/
|
|
28
|
-
const clearStartMocks = () => {
|
|
29
|
-
clearAllServerFnMocks();
|
|
30
|
-
clearAllMiddlewareMocks();
|
|
31
|
-
};
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/mockServerFn.ts
|
|
34
|
-
const hasKey = (value, key) => typeof value === "object" && value !== null && key in value;
|
|
35
|
-
const toCallableOptions = (ctx) => {
|
|
36
|
-
if (!hasKey(ctx, "data")) return ctx;
|
|
37
|
-
const source = ctx;
|
|
38
|
-
return {
|
|
39
|
-
data: source.data,
|
|
40
|
-
...source.headers !== void 0 ? { headers: source.headers } : {},
|
|
41
|
-
...source.signal !== void 0 ? { signal: source.signal } : {},
|
|
42
|
-
...source.fetch !== void 0 ? { fetch: source.fetch } : {}
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Install a mock implementation for a TanStack Start server function.
|
|
47
|
-
*
|
|
48
|
-
* @param fn - The server function created by `createServerFn().handler(...)`.
|
|
49
|
-
* @param impl - A {@link ServerFnMock} that replaces the real handler for the
|
|
50
|
-
* duration of the test. It receives the same callable-shape arguments (e.g.
|
|
51
|
-
* `{ data }`) as the original function.
|
|
52
|
-
* @returns A disposer function that restores the original implementation when
|
|
53
|
-
* called. Alternatively, call {@link clearStartMocks} to remove all mocks at
|
|
54
|
-
* once.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* import { createServerFn } from '@tanstack/react-start';
|
|
59
|
-
* import { mockServerFn } from '@tanstack-router-testing/react-start-testing';
|
|
60
|
-
*
|
|
61
|
-
* const listOrders = createServerFn()
|
|
62
|
-
* .validator((input: { userId: string }) => input)
|
|
63
|
-
* .handler(async ({ data }) => db.orders.findMany(data.userId));
|
|
64
|
-
*
|
|
65
|
-
* const dispose = mockServerFn(listOrders, async ({ data }) => [
|
|
66
|
-
* { id: '1', userId: data.userId, total: 42 },
|
|
67
|
-
* ]);
|
|
68
|
-
*
|
|
69
|
-
* // ... run your test ...
|
|
70
|
-
* dispose();
|
|
71
|
-
* ```
|
|
72
|
-
*
|
|
73
|
-
* @remarks
|
|
74
|
-
* The mock is authored against the public callable shape, so a server function
|
|
75
|
-
* normally called as `listOrders({ data })` is mocked with that same signature.
|
|
76
|
-
* Internal context fields are normalised automatically before reaching the mock.
|
|
77
|
-
*/
|
|
78
|
-
const mockServerFn = (fn, impl) => {
|
|
79
|
-
const handler = (ctx) => impl(toCallableOptions(ctx));
|
|
80
|
-
return setServerFnMock(fn, handler);
|
|
81
|
-
};
|
|
82
|
-
//#endregion
|
|
83
|
-
//#region src/mockMiddleware.ts
|
|
84
|
-
/**
|
|
85
|
-
* Override one or both phases of a registered middleware.
|
|
86
|
-
*
|
|
87
|
-
* @param mw - The middleware object returned by
|
|
88
|
-
* `createMiddleware().server(...).client(...)`.
|
|
89
|
-
* @param options - A {@link MockMiddlewareOptions} object specifying which
|
|
90
|
-
* phases to replace.
|
|
91
|
-
* @returns A disposer function that restores the original middleware handlers.
|
|
92
|
-
* Alternatively, call {@link clearStartMocks} to remove all mocks at once.
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```ts
|
|
96
|
-
* import { createMiddleware } from '@tanstack/react-start';
|
|
97
|
-
* import { mockMiddleware } from '@tanstack-router-testing/react-start-testing';
|
|
98
|
-
*
|
|
99
|
-
* const authMiddleware = createMiddleware()
|
|
100
|
-
* .server(async ({ next }) => next({ context: { user: await getUser() } }))
|
|
101
|
-
* .client(async ({ next }) => next());
|
|
102
|
-
*
|
|
103
|
-
* const dispose = mockMiddleware(authMiddleware, {
|
|
104
|
-
* server: async ({ next }) => next({ context: { user: { id: 'test-user' } } }),
|
|
105
|
-
* });
|
|
106
|
-
*
|
|
107
|
-
* // ... run your test ...
|
|
108
|
-
* dispose();
|
|
109
|
-
* ```
|
|
110
|
-
*
|
|
111
|
-
* @throws If `mw` is not registered. Registration is the shim's
|
|
112
|
-
* responsibility (see ADR 0001).
|
|
113
|
-
*
|
|
114
|
-
* @remarks
|
|
115
|
-
* Server functions are invoked directly and mocked middleware participates in
|
|
116
|
-
* that normal call path. Only the phases you specify in `options` are replaced;
|
|
117
|
-
* the rest continue to run their real implementations.
|
|
118
|
-
*/
|
|
119
|
-
const mockMiddleware = (mw, options) => setMiddlewareMock(mw, options);
|
|
120
|
-
//#endregion
|
|
121
|
-
//#region src/isomorphic.ts
|
|
122
|
-
/**
|
|
123
|
-
* Execute `fn` with the simulated TanStack Start environment forced to `env`,
|
|
124
|
-
* then restore the prior value.
|
|
125
|
-
*
|
|
126
|
-
* @typeParam T - The return type of `fn`.
|
|
127
|
-
* @param env - The environment to simulate: `'server'` or `'client'`.
|
|
128
|
-
* @param fn - A synchronous or asynchronous function to run inside the
|
|
129
|
-
* simulated environment.
|
|
130
|
-
* @returns A `Promise` resolving to the return value of `fn`.
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* ```ts
|
|
134
|
-
* import { runInStartEnv } from '@tanstack-router-testing/react-start-testing';
|
|
135
|
-
*
|
|
136
|
-
* const result = await runInStartEnv('server', () => {
|
|
137
|
-
* // Code here sees `import.meta.env.SSR === true`
|
|
138
|
-
* return fetchDataOnServer();
|
|
139
|
-
* });
|
|
140
|
-
* ```
|
|
141
|
-
*
|
|
142
|
-
* @remarks
|
|
143
|
-
* The environment is scoped to the execution of `fn` and is restored
|
|
144
|
-
* automatically even if `fn` throws. Used internally by
|
|
145
|
-
* {@link createStartTestRuntime} to set the environment for each
|
|
146
|
-
* {@link StartTestRuntime.run | run} invocation.
|
|
147
|
-
*/
|
|
148
|
-
const runInStartEnv = async (env, fn) => runInEnv(env, fn);
|
|
149
|
-
//#endregion
|
|
150
7
|
//#region src/runtime.ts
|
|
151
8
|
/**
|
|
152
9
|
* Create a {@link StartTestRuntime} for executing server functions in a
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/clearStartMocks.ts","../src/mockServerFn.ts","../src/mockMiddleware.ts","../src/isomorphic.ts","../src/runtime.ts","../src/rsc.tsx","../src/index.ts"],"sourcesContent":["import { clearAllMiddlewareMocks, clearAllServerFnMocks } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Clear every server-function and middleware mock installed by\n * {@link mockServerFn} or {@link mockMiddleware}.\n *\n * @returns `void`.\n *\n * @example\n * ```ts\n * import { afterEach } from 'vitest';\n * import { clearStartMocks } from '@tanstack-router-testing/react-start-testing';\n *\n * afterEach(() => {\n * clearStartMocks();\n * });\n * ```\n *\n * @remarks\n * This is the same function wired to {@link StartTestRuntime.cleanup}, so you\n * only need to call it explicitly when installing mocks outside of a runtime\n * (i.e. via {@link mockServerFn} / {@link mockMiddleware} directly).\n */\nexport const clearStartMocks = (): void => {\n clearAllServerFnMocks();\n clearAllMiddlewareMocks();\n};\n","import type { AnyFn } from '@tanstack-router-testing/router-testing-core';\n\nimport { setServerFnMock } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Catch-all type representing any TanStack Start server function.\n *\n * @remarks\n * Used as a generic constraint in {@link mockServerFn} and {@link ServerFnMock}\n * to accept any function created by `createServerFn().handler(...)`.\n */\nexport type AnyServerFn = (...args: never[]) => unknown;\n\n/**\n * The mock implementation signature for a server function of type `TFn`.\n *\n * @typeParam TFn - The server function type being mocked.\n *\n * @remarks\n * The mock receives the same callable-shape arguments as the real server\n * function (e.g. `{ data }`) and must return a compatible result. Full generic\n * inference is preserved so autocomplete works identically to the real call.\n *\n * @see {@link mockServerFn}\n */\nexport type ServerFnMock<TFn extends AnyServerFn> = (...args: Parameters<TFn>) => ReturnType<TFn>;\n\nconst hasKey = (value: unknown, key: string): boolean => typeof value === 'object' && value !== null && key in value;\n\nconst toCallableOptions = (ctx: unknown): unknown => {\n if (!hasKey(ctx, 'data')) return ctx;\n\n const source = ctx as {\n readonly data?: unknown;\n readonly headers?: HeadersInit;\n readonly signal?: AbortSignal;\n readonly fetch?: typeof globalThis.fetch;\n };\n\n return {\n data: source.data,\n ...(source.headers !== undefined ? { headers: source.headers } : {}),\n ...(source.signal !== undefined ? { signal: source.signal } : {}),\n ...(source.fetch !== undefined ? { fetch: source.fetch } : {}),\n };\n};\n\n/**\n * Install a mock implementation for a TanStack Start server function.\n *\n * @param fn - The server function created by `createServerFn().handler(...)`.\n * @param impl - A {@link ServerFnMock} that replaces the real handler for the\n * duration of the test. It receives the same callable-shape arguments (e.g.\n * `{ data }`) as the original function.\n * @returns A disposer function that restores the original implementation when\n * called. Alternatively, call {@link clearStartMocks} to remove all mocks at\n * once.\n *\n * @example\n * ```ts\n * import { createServerFn } from '@tanstack/react-start';\n * import { mockServerFn } from '@tanstack-router-testing/react-start-testing';\n *\n * const listOrders = createServerFn()\n * .validator((input: { userId: string }) => input)\n * .handler(async ({ data }) => db.orders.findMany(data.userId));\n *\n * const dispose = mockServerFn(listOrders, async ({ data }) => [\n * { id: '1', userId: data.userId, total: 42 },\n * ]);\n *\n * // ... run your test ...\n * dispose();\n * ```\n *\n * @remarks\n * The mock is authored against the public callable shape, so a server function\n * normally called as `listOrders({ data })` is mocked with that same signature.\n * Internal context fields are normalised automatically before reaching the mock.\n */\nexport const mockServerFn = <TFn extends AnyServerFn>(fn: TFn, impl: ServerFnMock<TFn>): (() => void) => {\n const handler: AnyFn = (ctx?: unknown) => (impl as AnyFn)(toCallableOptions(ctx));\n return setServerFnMock(fn as unknown as AnyFn, handler);\n};\n","import type { AnyFn } from '@tanstack-router-testing/router-testing-core';\n\nimport { setMiddlewareMock } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Phase override options for {@link mockMiddleware}.\n *\n * @remarks\n * Provide `client`, `server`, or both. Omitted keys leave the corresponding\n * phase untouched, so you can mock only the server side without affecting the\n * client phase and vice-versa.\n */\nexport interface MockMiddlewareOptions {\n /** Override for the `.client()` phase. When omitted the real client handler runs. */\n readonly client?: AnyFn;\n /** Override for the `.server()` phase. When omitted the real server handler runs. */\n readonly server?: AnyFn;\n}\n\n/**\n * Override one or both phases of a registered middleware.\n *\n * @param mw - The middleware object returned by\n * `createMiddleware().server(...).client(...)`.\n * @param options - A {@link MockMiddlewareOptions} object specifying which\n * phases to replace.\n * @returns A disposer function that restores the original middleware handlers.\n * Alternatively, call {@link clearStartMocks} to remove all mocks at once.\n *\n * @example\n * ```ts\n * import { createMiddleware } from '@tanstack/react-start';\n * import { mockMiddleware } from '@tanstack-router-testing/react-start-testing';\n *\n * const authMiddleware = createMiddleware()\n * .server(async ({ next }) => next({ context: { user: await getUser() } }))\n * .client(async ({ next }) => next());\n *\n * const dispose = mockMiddleware(authMiddleware, {\n * server: async ({ next }) => next({ context: { user: { id: 'test-user' } } }),\n * });\n *\n * // ... run your test ...\n * dispose();\n * ```\n *\n * @throws If `mw` is not registered. Registration is the shim's\n * responsibility (see ADR 0001).\n *\n * @remarks\n * Server functions are invoked directly and mocked middleware participates in\n * that normal call path. Only the phases you specify in `options` are replaced;\n * the rest continue to run their real implementations.\n */\nexport const mockMiddleware = (mw: object, options: MockMiddlewareOptions): (() => void) => setMiddlewareMock(mw, options);\n","import type { TestEnv } from '@tanstack-router-testing/router-testing-core';\n\nimport { runInEnv } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Execute `fn` with the simulated TanStack Start environment forced to `env`,\n * then restore the prior value.\n *\n * @typeParam T - The return type of `fn`.\n * @param env - The environment to simulate: `'server'` or `'client'`.\n * @param fn - A synchronous or asynchronous function to run inside the\n * simulated environment.\n * @returns A `Promise` resolving to the return value of `fn`.\n *\n * @example\n * ```ts\n * import { runInStartEnv } from '@tanstack-router-testing/react-start-testing';\n *\n * const result = await runInStartEnv('server', () => {\n * // Code here sees `import.meta.env.SSR === true`\n * return fetchDataOnServer();\n * });\n * ```\n *\n * @remarks\n * The environment is scoped to the execution of `fn` and is restored\n * automatically even if `fn` throws. Used internally by\n * {@link createStartTestRuntime} to set the environment for each\n * {@link StartTestRuntime.run | run} invocation.\n */\nexport const runInStartEnv = async <T>(env: TestEnv, fn: () => T | Promise<T>): Promise<T> => runInEnv(env, fn);\n","import type { TestEnv } from '@tanstack-router-testing/router-testing-core';\nimport type { AnyRouter } from '@tanstack/react-router';\nimport type { AnyStartInstanceOptions } from '@tanstack/start-client-core';\nimport type { StartHandlerType, StartStorageContext } from '@tanstack/start-storage-context';\n\nimport { runWithStartContext } from '@tanstack/start-storage-context';\n\nimport { clearStartMocks } from './clearStartMocks.ts';\nimport { runInStartEnv } from './isomorphic.ts';\nimport { __setStartOptionsForTesting } from './shim.ts';\n\n/**\n * Configuration for {@link createStartTestRuntime}.\n *\n * @remarks\n * At most one of `startInstance` and `startOptions` should be provided. If both\n * are given, `startOptions` takes precedence. When neither is supplied the\n * runtime creates an empty options object.\n */\nexport interface StartTestRuntimeOptions {\n /**\n * A Start instance whose `getOptions()` method is called once during\n * runtime creation. Ignored when {@link startOptions} is also provided.\n */\n readonly startInstance?: {\n readonly getOptions: () => AnyStartInstanceOptions | Promise<AnyStartInstanceOptions>;\n };\n /** Explicit Start options to use instead of resolving from a `startInstance`. */\n readonly startOptions?: AnyStartInstanceOptions;\n /**\n * The incoming request available to server functions via `getRequest()`.\n * Accepts a full `Request`, a URL string, or a `URL` object.\n * Defaults to `http://tanstack-router-testing.test/`.\n */\n readonly request?: Request | string | URL;\n /** The TanStack Router instance made available via `getRouter()` inside server functions. */\n readonly router?: AnyRouter;\n /** Initial middleware context. Merged into each call's context before global request middlewares run. */\n readonly context?: unknown;\n /** Default simulated environment. Defaults to `'server'`. */\n readonly env?: TestEnv;\n /** Default handler type passed to the storage context. Defaults to `'serverFn'`. */\n readonly handlerType?: StartHandlerType;\n}\n\n/**\n * Per-invocation overrides passed to {@link StartTestRuntime.run} and\n * {@link StartTestRuntime.call}.\n *\n * @remarks\n * Every property mirrors a field from {@link StartTestRuntimeOptions}. When\n * provided here it takes precedence over the runtime-level default for that\n * single invocation only.\n */\nexport interface StartTestRunOptions {\n /** Override the request for this invocation. */\n readonly request?: Request | string | URL;\n /** Override the middleware context for this invocation. */\n readonly context?: unknown;\n /** Override the simulated environment (`'server'` or `'client'`) for this invocation. */\n readonly env?: TestEnv;\n /** Override the handler type for this invocation. */\n readonly handlerType?: StartHandlerType;\n}\n\n/**\n * A test runtime that simulates the TanStack Start server environment.\n *\n * @remarks\n * Created by {@link createStartTestRuntime}. Provides the storage context,\n * request, and environment that server functions expect at runtime. Call\n * {@link cleanup} (or {@link clearStartMocks}) in `afterEach` to restore all\n * mocks.\n */\nexport interface StartTestRuntime {\n /** The `Request` object available to server functions via `getRequest()`. */\n readonly request: Request;\n /** The resolved Start options used by the runtime. */\n readonly startOptions: AnyStartInstanceOptions;\n /**\n * Run an arbitrary function inside the Start storage context.\n *\n * @typeParam T - The return type of `fn`.\n * @param fn - The function to execute.\n * @param options - Optional per-invocation overrides. See {@link StartTestRunOptions}.\n * @returns A `Promise` resolving to the return value of `fn`.\n */\n readonly run: <T>(fn: () => T | Promise<T>, options?: StartTestRunOptions) => Promise<T>;\n /**\n * Invoke a server function (or any callable) with explicit arguments inside\n * the Start storage context.\n *\n * @typeParam TArgs - Tuple of argument types.\n * @typeParam TReturn - The return type of `fn`.\n * @param fn - The function to call.\n * @param args - Arguments forwarded to `fn`.\n * @param options - Optional per-invocation overrides. See {@link StartTestRunOptions}.\n * @returns A `Promise` resolving to the awaited return value of `fn`.\n */\n readonly call: <TArgs extends readonly unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn | Promise<TReturn>,\n args: TArgs,\n options?: StartTestRunOptions,\n ) => Promise<Awaited<TReturn>>;\n /**\n * Remove all server-function and middleware mocks. Equivalent to calling\n * {@link clearStartMocks}.\n */\n readonly cleanup: () => void;\n}\n\n/**\n * Create a {@link StartTestRuntime} for executing server functions in a\n * simulated TanStack Start environment.\n *\n * @param options - Runtime configuration. See {@link StartTestRuntimeOptions}.\n * @returns A `Promise` resolving to a {@link StartTestRuntime} instance.\n *\n * @example\n * ```ts\n * import { createServerFn } from '@tanstack/react-start';\n * import {\n * createStartTestRuntime,\n * mockServerFn,\n * } from '@tanstack-router-testing/react-start-testing';\n *\n * const runtime = await createStartTestRuntime({\n * request: 'http://localhost:3000/api/orders',\n * env: 'server',\n * });\n *\n * const listOrders = createServerFn()\n * .validator((input: { userId: string }) => input)\n * .handler(async ({ data }) => [{ id: '1', userId: data.userId }]);\n *\n * mockServerFn(listOrders, async ({ data }) => [\n * { id: 'mock-1', userId: data.userId },\n * ]);\n *\n * const orders = await runtime.call(listOrders, [{ data: { userId: 'u1' } }]);\n * // orders === [{ id: 'mock-1', userId: 'u1' }]\n *\n * runtime.cleanup();\n * ```\n *\n * @remarks\n * The runtime resolves Start options from either `startOptions` or\n * `startInstance.getOptions()`, sets up the Start storage context, and\n * executes global request middlewares before each invocation.\n */\nexport const createStartTestRuntime = async (options: StartTestRuntimeOptions = {}): Promise<StartTestRuntime> => {\n const startOptions = options.startOptions ?? (await options.startInstance?.getOptions()) ?? ({} as AnyStartInstanceOptions);\n const request = toRequest(options.request);\n\n __setStartOptionsForTesting(startOptions);\n\n const createContext = (runOptions: StartTestRunOptions = {}): StartStorageContext => ({\n getRouter: () => {\n if (!options.router) {\n throw new Error('[tanstack-router-testing] createStartTestRuntime: no router was provided for this test runtime.');\n }\n return options.router as never;\n },\n request: toRequest(runOptions.request ?? request),\n startOptions,\n contextAfterGlobalMiddlewares: runOptions.context ?? options.context ?? {},\n executedRequestMiddlewares: new Set(),\n handlerType: runOptions.handlerType ?? options.handlerType ?? 'serverFn',\n });\n\n const runtime: StartTestRuntime = {\n request,\n startOptions,\n run: async (fn, runOptions) => {\n const env = runOptions?.env ?? options.env ?? 'server';\n const storage = createContext(runOptions);\n return runWithStartContext(storage, async () => {\n storage.contextAfterGlobalMiddlewares = await executeGlobalRequestMiddlewares(storage, storage.contextAfterGlobalMiddlewares);\n return runInStartEnv(env, fn);\n });\n },\n call: <TArgs extends readonly unknown[], TReturn>(fn: (...args: TArgs) => TReturn | Promise<TReturn>, args: TArgs, runOptions?: StartTestRunOptions) =>\n runtime.run(() => fn(...args), runOptions) as Promise<Awaited<TReturn>>,\n cleanup: clearStartMocks,\n };\n\n return runtime;\n};\n\nconst toRequest = (request: Request | string | URL | undefined): Request => {\n if (request instanceof Request) return request;\n const url = request?.toString() ?? 'http://tanstack-router-testing.test/';\n return new Request(url);\n};\n\nconst executeGlobalRequestMiddlewares = async (storage: StartStorageContext, initialContext: unknown): Promise<unknown> => {\n const middlewares = [...((storage.startOptions?.requestMiddleware ?? []) as { readonly options?: { readonly server?: unknown } }[])];\n const { pathname } = new URL(storage.request.url);\n\n const next = async (\n parentContext: unknown,\n ctx: { readonly context?: unknown } | undefined = {},\n ): Promise<{ readonly context: unknown; readonly response: Response }> => {\n const middleware = middlewares.shift();\n const context = mergeContext(parentContext, ctx.context);\n if (!middleware) {\n return {\n context,\n response: new Response(null),\n };\n }\n\n storage.executedRequestMiddlewares.add(middleware);\n\n const server = middleware.options?.server;\n if (typeof server !== 'function') return next(context);\n\n const result = await server({\n request: storage.request,\n pathname,\n context,\n next: (nextCtx?: { readonly context?: unknown }) => next(context, nextCtx),\n });\n\n if (result instanceof Response) {\n return { context, response: result };\n }\n\n return {\n context: mergeContext(context, (result as { readonly context?: unknown } | undefined)?.context),\n response: (result as { readonly response?: Response } | undefined)?.response ?? new Response(null),\n };\n };\n\n const result = await next(initialContext);\n return result.context;\n};\n\nconst mergeContext = (left: unknown, right: unknown): unknown => {\n if (isRecord(left) && isRecord(right)) {\n return { ...left, ...right };\n }\n return right ?? left ?? {};\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\n","import type { StartTestRuntime, StartTestRuntimeOptions } from './runtime.ts';\nimport type { ComponentType } from 'react';\n\nimport { createElement } from 'react';\nimport { renderToReadableStream, renderToString } from 'react-dom/server';\n\nimport { createStartTestRuntime } from './runtime.ts';\n\n/**\n * Configuration for {@link createRscTestRuntime}.\n *\n * @remarks\n * Extends {@link StartTestRuntimeOptions} with an additional `streaming` flag\n * that controls the server rendering mode.\n */\nexport interface RscTestRuntimeOptions extends StartTestRuntimeOptions {\n /**\n * When `true`, renders via `renderToReadableStream` and collects individual\n * chunks. When `false` (default), uses `renderToString` for a single\n * synchronous HTML output.\n */\n readonly streaming?: boolean;\n}\n\n/**\n * The result of rendering a React Server Component via\n * {@link RscTestRuntime.renderServerComponent}.\n */\nexport interface RscRenderResult {\n /** The complete HTML string produced by the render. */\n readonly html: string;\n /**\n * A cloned `ReadableStream` of the raw bytes. Only present when the runtime\n * was created with `streaming: true`; otherwise `null`.\n */\n readonly stream: ReadableStream<Uint8Array> | null;\n /**\n * Decoded text chunks collected from the stream. Empty when `streaming` is\n * `false`.\n */\n readonly chunks: readonly string[];\n}\n\n/**\n * Extended test runtime that adds React Server Component rendering on top of\n * the base {@link StartTestRuntime}.\n *\n * @remarks\n * Created by {@link createRscTestRuntime}. Inherits all members from\n * {@link StartTestRuntime} and adds {@link renderServerComponent}.\n */\nexport interface RscTestRuntime extends StartTestRuntime {\n /**\n * Render a React Server Component to HTML.\n *\n * @typeParam TProps - The component's props type.\n * @param component - The React component to render.\n * @param props - Props forwarded to `createElement(component, props)`.\n * @returns A `Promise` resolving to an {@link RscRenderResult} containing the\n * rendered HTML and, when streaming is enabled, the raw stream and decoded\n * chunks.\n */\n readonly renderServerComponent: <TProps extends Record<string, unknown>>(component: ComponentType<TProps>, props: TProps) => Promise<RscRenderResult>;\n}\n\n/**\n * Create an {@link RscTestRuntime} for rendering React Server Components in a\n * simulated TanStack Start environment.\n *\n * @param options - Runtime configuration. See {@link RscTestRuntimeOptions}.\n * @returns A `Promise` resolving to an {@link RscTestRuntime} instance.\n *\n * @example\n * ```ts\n * import { createRscTestRuntime } from '@tanstack-router-testing/react-start-testing';\n *\n * const runtime = await createRscTestRuntime({ streaming: true });\n *\n * function Greeting({ name }: { name: string }) {\n * return <h1>Hello, {name}!</h1>;\n * }\n *\n * const { html, chunks } = await runtime.renderServerComponent(Greeting, {\n * name: 'TanStack',\n * });\n * // html === '<h1>Hello, TanStack!</h1>'\n *\n * runtime.cleanup();\n * ```\n *\n * @remarks\n * Delegates to {@link createStartTestRuntime} for the base runtime, then layers\n * on `renderServerComponent` which uses `react-dom/server` under the hood. Set\n * `streaming: true` in options to render via `renderToReadableStream` instead of\n * the default `renderToString`.\n */\nexport const createRscTestRuntime = async (options: RscTestRuntimeOptions = {}): Promise<RscTestRuntime> => {\n const base = await createStartTestRuntime(options);\n const streaming = options.streaming ?? false;\n\n return {\n ...base,\n renderServerComponent: async <TProps extends Record<string, unknown>>(component: ComponentType<TProps>, props: TProps): Promise<RscRenderResult> => {\n const element = createElement(component, props);\n\n if (!streaming) {\n const html = renderToString(element);\n return { html, stream: null, chunks: [] };\n }\n\n const stream = await renderToReadableStream(element);\n const chunks: string[] = [];\n const decoder = new TextDecoder();\n\n const [collectStream, returnStream] = stream.tee();\n\n const reader = collectStream.getReader();\n const collectChunks = async (): Promise<void> => {\n const result = await reader.read();\n if (result.value !== undefined) {\n chunks.push(decoder.decode(result.value, { stream: !result.done }));\n }\n if (!result.done) await collectChunks();\n };\n await collectChunks();\n\n const html = chunks.join('');\n return { html, stream: returnStream, chunks };\n },\n };\n};\n","/**\n * Upstream-shaped test helpers for `@tanstack/react-start`.\n *\n * Server functions are called directly in tests, exactly as production code\n * calls them. This package only exposes mock and environment controls.\n */\n\nexport { type CallMiddlewareOptions, type CallMiddlewareResult, callMiddleware } from '@tanstack-router-testing/router-testing-core';\nexport { clearStartMocks } from './clearStartMocks.ts';\nexport { type AnyServerFn, mockServerFn, type ServerFnMock } from './mockServerFn.ts';\nexport { type MockMiddlewareOptions, mockMiddleware } from './mockMiddleware.ts';\nexport { runInStartEnv } from './isomorphic.ts';\nexport { createRscTestRuntime, type RscRenderResult, type RscTestRuntime, type RscTestRuntimeOptions } from './rsc.tsx';\nexport { createStartTestRuntime, type StartTestRuntime, type StartTestRuntimeOptions, type StartTestRunOptions } from './runtime.ts';\n\n/**\n * Current package version. Bumped at release time.\n */\nexport const VERSION = '0.0.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,wBAA8B;AACzC,wBAAuB;AACvB,0BAAyB;;;;ACE3B,MAAM,UAAU,OAAgB,QAAyB,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAO;AAE/G,MAAM,qBAAqB,QAA0B;AACnD,KAAI,CAAC,OAAO,KAAK,OAAO,CAAE,QAAO;CAEjC,MAAM,SAAS;AAOf,QAAO;EACL,MAAM,OAAO;EACb,GAAI,OAAO,YAAY,KAAA,IAAY,EAAE,SAAS,OAAO,SAAS,GAAG,EAAE;EACnE,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;EAChE,GAAI,OAAO,UAAU,KAAA,IAAY,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;EAC9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCH,MAAa,gBAAyC,IAAS,SAA0C;CACvG,MAAM,WAAkB,QAAmB,KAAe,kBAAkB,IAAI,CAAC;AACjF,QAAO,gBAAgB,IAAwB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5BzD,MAAa,kBAAkB,IAAY,YAAiD,kBAAkB,IAAI,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxB1H,MAAa,gBAAgB,OAAU,KAAc,OAAyC,SAAS,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACwH/G,MAAa,yBAAyB,OAAO,UAAmC,EAAE,KAAgC;CAChH,MAAM,eAAe,QAAQ,gBAAiB,MAAM,QAAQ,eAAe,YAAY,IAAM,EAAE;CAC/F,MAAM,UAAU,UAAU,QAAQ,QAAQ;AAE1C,6BAA4B,aAAa;CAEzC,MAAM,iBAAiB,aAAkC,EAAE,MAA2B;EACpF,iBAAiB;AACf,OAAI,CAAC,QAAQ,OACX,OAAM,IAAI,MAAM,kGAAkG;AAEpH,UAAO,QAAQ;;EAEjB,SAAS,UAAU,WAAW,WAAW,QAAQ;EACjD;EACA,+BAA+B,WAAW,WAAW,QAAQ,WAAW,EAAE;EAC1E,4CAA4B,IAAI,KAAK;EACrC,aAAa,WAAW,eAAe,QAAQ,eAAe;EAC/D;CAED,MAAM,UAA4B;EAChC;EACA;EACA,KAAK,OAAO,IAAI,eAAe;GAC7B,MAAM,MAAM,YAAY,OAAO,QAAQ,OAAO;GAC9C,MAAM,UAAU,cAAc,WAAW;AACzC,UAAO,oBAAoB,SAAS,YAAY;AAC9C,YAAQ,gCAAgC,MAAM,gCAAgC,SAAS,QAAQ,8BAA8B;AAC7H,WAAO,cAAc,KAAK,GAAG;KAC7B;;EAEJ,OAAkD,IAAoD,MAAa,eACjH,QAAQ,UAAU,GAAG,GAAG,KAAK,EAAE,WAAW;EAC5C,SAAS;EACV;AAED,QAAO;;AAGT,MAAM,aAAa,YAAyD;AAC1E,KAAI,mBAAmB,QAAS,QAAO;CACvC,MAAM,MAAM,SAAS,UAAU,IAAI;AACnC,QAAO,IAAI,QAAQ,IAAI;;AAGzB,MAAM,kCAAkC,OAAO,SAA8B,mBAA8C;CACzH,MAAM,cAAc,CAAC,GAAK,QAAQ,cAAc,qBAAqB,EAAE,CAA6D;CACpI,MAAM,EAAE,aAAa,IAAI,IAAI,QAAQ,QAAQ,IAAI;CAEjD,MAAM,OAAO,OACX,eACA,MAAkD,EAAE,KACoB;EACxE,MAAM,aAAa,YAAY,OAAO;EACtC,MAAM,UAAU,aAAa,eAAe,IAAI,QAAQ;AACxD,MAAI,CAAC,WACH,QAAO;GACL;GACA,UAAU,IAAI,SAAS,KAAK;GAC7B;AAGH,UAAQ,2BAA2B,IAAI,WAAW;EAElD,MAAM,SAAS,WAAW,SAAS;AACnC,MAAI,OAAO,WAAW,WAAY,QAAO,KAAK,QAAQ;EAEtD,MAAM,SAAS,MAAM,OAAO;GAC1B,SAAS,QAAQ;GACjB;GACA;GACA,OAAO,YAA6C,KAAK,SAAS,QAAQ;GAC3E,CAAC;AAEF,MAAI,kBAAkB,SACpB,QAAO;GAAE;GAAS,UAAU;GAAQ;AAGtC,SAAO;GACL,SAAS,aAAa,SAAU,QAAuD,QAAQ;GAC/F,UAAW,QAAyD,YAAY,IAAI,SAAS,KAAK;GACnG;;AAIH,SAAO,MADc,KAAK,eAAe,EAC3B;;AAGhB,MAAM,gBAAgB,MAAe,UAA4B;AAC/D,KAAI,SAAS,KAAK,IAAI,SAAS,MAAM,CACnC,QAAO;EAAE,GAAG;EAAM,GAAG;EAAO;AAE9B,QAAO,SAAS,QAAQ,EAAE;;AAG5B,MAAM,YAAY,UAAqD,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrJ3I,MAAa,uBAAuB,OAAO,UAAiC,EAAE,KAA8B;CAC1G,MAAM,OAAO,MAAM,uBAAuB,QAAQ;CAClD,MAAM,YAAY,QAAQ,aAAa;AAEvC,QAAO;EACL,GAAG;EACH,uBAAuB,OAA+C,WAAkC,UAA4C;GAClJ,MAAM,UAAU,cAAc,WAAW,MAAM;AAE/C,OAAI,CAAC,UAEH,QAAO;IAAE,MADI,eAAe,QACf;IAAE,QAAQ;IAAM,QAAQ,EAAE;IAAE;GAG3C,MAAM,SAAS,MAAM,uBAAuB,QAAQ;GACpD,MAAM,SAAmB,EAAE;GAC3B,MAAM,UAAU,IAAI,aAAa;GAEjC,MAAM,CAAC,eAAe,gBAAgB,OAAO,KAAK;GAElD,MAAM,SAAS,cAAc,WAAW;GACxC,MAAM,gBAAgB,YAA2B;IAC/C,MAAM,SAAS,MAAM,OAAO,MAAM;AAClC,QAAI,OAAO,UAAU,KAAA,EACnB,QAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,EAAE,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC;AAErE,QAAI,CAAC,OAAO,KAAM,OAAM,eAAe;;AAEzC,SAAM,eAAe;AAGrB,UAAO;IAAE,MADI,OAAO,KAAK,GACZ;IAAE,QAAQ;IAAc;IAAQ;;EAEhD;;;;;;;AC/GH,MAAa,UAAU"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/runtime.ts","../src/rsc.tsx","../src/index.ts"],"sourcesContent":["import type { TestEnv } from '@tanstack-router-testing/router-testing-core';\nimport type { AnyRouter } from '@tanstack/react-router';\nimport type { AnyStartInstanceOptions } from '@tanstack/start-client-core';\nimport type { StartHandlerType, StartStorageContext } from '@tanstack/start-storage-context';\n\nimport { runWithStartContext } from '@tanstack/start-storage-context';\n\nimport { clearStartMocks } from './clearStartMocks.ts';\nimport { runInStartEnv } from './isomorphic.ts';\nimport { __setStartOptionsForTesting } from './shim.ts';\n\n/**\n * Configuration for {@link createStartTestRuntime}.\n *\n * @remarks\n * At most one of `startInstance` and `startOptions` should be provided. If both\n * are given, `startOptions` takes precedence. When neither is supplied the\n * runtime creates an empty options object.\n */\nexport interface StartTestRuntimeOptions {\n /**\n * A Start instance whose `getOptions()` method is called once during\n * runtime creation. Ignored when {@link startOptions} is also provided.\n */\n readonly startInstance?: {\n readonly getOptions: () => AnyStartInstanceOptions | Promise<AnyStartInstanceOptions>;\n };\n /** Explicit Start options to use instead of resolving from a `startInstance`. */\n readonly startOptions?: AnyStartInstanceOptions;\n /**\n * The incoming request available to server functions via `getRequest()`.\n * Accepts a full `Request`, a URL string, or a `URL` object.\n * Defaults to `http://tanstack-router-testing.test/`.\n */\n readonly request?: Request | string | URL;\n /** The TanStack Router instance made available via `getRouter()` inside server functions. */\n readonly router?: AnyRouter;\n /** Initial middleware context. Merged into each call's context before global request middlewares run. */\n readonly context?: unknown;\n /** Default simulated environment. Defaults to `'server'`. */\n readonly env?: TestEnv;\n /** Default handler type passed to the storage context. Defaults to `'serverFn'`. */\n readonly handlerType?: StartHandlerType;\n}\n\n/**\n * Per-invocation overrides passed to {@link StartTestRuntime.run} and\n * {@link StartTestRuntime.call}.\n *\n * @remarks\n * Every property mirrors a field from {@link StartTestRuntimeOptions}. When\n * provided here it takes precedence over the runtime-level default for that\n * single invocation only.\n */\nexport interface StartTestRunOptions {\n /** Override the request for this invocation. */\n readonly request?: Request | string | URL;\n /** Override the middleware context for this invocation. */\n readonly context?: unknown;\n /** Override the simulated environment (`'server'` or `'client'`) for this invocation. */\n readonly env?: TestEnv;\n /** Override the handler type for this invocation. */\n readonly handlerType?: StartHandlerType;\n}\n\n/**\n * A test runtime that simulates the TanStack Start server environment.\n *\n * @remarks\n * Created by {@link createStartTestRuntime}. Provides the storage context,\n * request, and environment that server functions expect at runtime. Call\n * {@link cleanup} (or {@link clearStartMocks}) in `afterEach` to restore all\n * mocks.\n */\nexport interface StartTestRuntime {\n /** The `Request` object available to server functions via `getRequest()`. */\n readonly request: Request;\n /** The resolved Start options used by the runtime. */\n readonly startOptions: AnyStartInstanceOptions;\n /**\n * Run an arbitrary function inside the Start storage context.\n *\n * @typeParam T - The return type of `fn`.\n * @param fn - The function to execute.\n * @param options - Optional per-invocation overrides. See {@link StartTestRunOptions}.\n * @returns A `Promise` resolving to the return value of `fn`.\n */\n readonly run: <T>(fn: () => T | Promise<T>, options?: StartTestRunOptions) => Promise<T>;\n /**\n * Invoke a server function (or any callable) with explicit arguments inside\n * the Start storage context.\n *\n * @typeParam TArgs - Tuple of argument types.\n * @typeParam TReturn - The return type of `fn`.\n * @param fn - The function to call.\n * @param args - Arguments forwarded to `fn`.\n * @param options - Optional per-invocation overrides. See {@link StartTestRunOptions}.\n * @returns A `Promise` resolving to the awaited return value of `fn`.\n */\n readonly call: <TArgs extends readonly unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn | Promise<TReturn>,\n args: TArgs,\n options?: StartTestRunOptions,\n ) => Promise<Awaited<TReturn>>;\n /**\n * Remove all server-function and middleware mocks. Equivalent to calling\n * {@link clearStartMocks}.\n */\n readonly cleanup: () => void;\n}\n\n/**\n * Create a {@link StartTestRuntime} for executing server functions in a\n * simulated TanStack Start environment.\n *\n * @param options - Runtime configuration. See {@link StartTestRuntimeOptions}.\n * @returns A `Promise` resolving to a {@link StartTestRuntime} instance.\n *\n * @example\n * ```ts\n * import { createServerFn } from '@tanstack/react-start';\n * import {\n * createStartTestRuntime,\n * mockServerFn,\n * } from '@tanstack-router-testing/react-start-testing';\n *\n * const runtime = await createStartTestRuntime({\n * request: 'http://localhost:3000/api/orders',\n * env: 'server',\n * });\n *\n * const listOrders = createServerFn()\n * .validator((input: { userId: string }) => input)\n * .handler(async ({ data }) => [{ id: '1', userId: data.userId }]);\n *\n * mockServerFn(listOrders, async ({ data }) => [\n * { id: 'mock-1', userId: data.userId },\n * ]);\n *\n * const orders = await runtime.call(listOrders, [{ data: { userId: 'u1' } }]);\n * // orders === [{ id: 'mock-1', userId: 'u1' }]\n *\n * runtime.cleanup();\n * ```\n *\n * @remarks\n * The runtime resolves Start options from either `startOptions` or\n * `startInstance.getOptions()`, sets up the Start storage context, and\n * executes global request middlewares before each invocation.\n */\nexport const createStartTestRuntime = async (options: StartTestRuntimeOptions = {}): Promise<StartTestRuntime> => {\n const startOptions = options.startOptions ?? (await options.startInstance?.getOptions()) ?? ({} as AnyStartInstanceOptions);\n const request = toRequest(options.request);\n\n __setStartOptionsForTesting(startOptions);\n\n const createContext = (runOptions: StartTestRunOptions = {}): StartStorageContext => ({\n getRouter: () => {\n if (!options.router) {\n throw new Error('[tanstack-router-testing] createStartTestRuntime: no router was provided for this test runtime.');\n }\n return options.router as never;\n },\n request: toRequest(runOptions.request ?? request),\n startOptions,\n contextAfterGlobalMiddlewares: runOptions.context ?? options.context ?? {},\n executedRequestMiddlewares: new Set(),\n handlerType: runOptions.handlerType ?? options.handlerType ?? 'serverFn',\n });\n\n const runtime: StartTestRuntime = {\n request,\n startOptions,\n run: async (fn, runOptions) => {\n const env = runOptions?.env ?? options.env ?? 'server';\n const storage = createContext(runOptions);\n return runWithStartContext(storage, async () => {\n storage.contextAfterGlobalMiddlewares = await executeGlobalRequestMiddlewares(storage, storage.contextAfterGlobalMiddlewares);\n return runInStartEnv(env, fn);\n });\n },\n call: <TArgs extends readonly unknown[], TReturn>(fn: (...args: TArgs) => TReturn | Promise<TReturn>, args: TArgs, runOptions?: StartTestRunOptions) =>\n runtime.run(() => fn(...args), runOptions) as Promise<Awaited<TReturn>>,\n cleanup: clearStartMocks,\n };\n\n return runtime;\n};\n\nconst toRequest = (request: Request | string | URL | undefined): Request => {\n if (request instanceof Request) return request;\n const url = request?.toString() ?? 'http://tanstack-router-testing.test/';\n return new Request(url);\n};\n\nconst executeGlobalRequestMiddlewares = async (storage: StartStorageContext, initialContext: unknown): Promise<unknown> => {\n const middlewares = [...((storage.startOptions?.requestMiddleware ?? []) as { readonly options?: { readonly server?: unknown } }[])];\n const { pathname } = new URL(storage.request.url);\n\n const next = async (\n parentContext: unknown,\n ctx: { readonly context?: unknown } | undefined = {},\n ): Promise<{ readonly context: unknown; readonly response: Response }> => {\n const middleware = middlewares.shift();\n const context = mergeContext(parentContext, ctx.context);\n if (!middleware) {\n return {\n context,\n response: new Response(null),\n };\n }\n\n storage.executedRequestMiddlewares.add(middleware);\n\n const server = middleware.options?.server;\n if (typeof server !== 'function') return next(context);\n\n const result = await server({\n request: storage.request,\n pathname,\n context,\n next: (nextCtx?: { readonly context?: unknown }) => next(context, nextCtx),\n });\n\n if (result instanceof Response) {\n return { context, response: result };\n }\n\n return {\n context: mergeContext(context, (result as { readonly context?: unknown } | undefined)?.context),\n response: (result as { readonly response?: Response } | undefined)?.response ?? new Response(null),\n };\n };\n\n const result = await next(initialContext);\n return result.context;\n};\n\nconst mergeContext = (left: unknown, right: unknown): unknown => {\n if (isRecord(left) && isRecord(right)) {\n return { ...left, ...right };\n }\n return right ?? left ?? {};\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\n","import type { StartTestRuntime, StartTestRuntimeOptions } from './runtime.ts';\nimport type { ComponentType } from 'react';\n\nimport { createElement } from 'react';\nimport { renderToReadableStream, renderToString } from 'react-dom/server';\n\nimport { createStartTestRuntime } from './runtime.ts';\n\n/**\n * Configuration for {@link createRscTestRuntime}.\n *\n * @remarks\n * Extends {@link StartTestRuntimeOptions} with an additional `streaming` flag\n * that controls the server rendering mode.\n */\nexport interface RscTestRuntimeOptions extends StartTestRuntimeOptions {\n /**\n * When `true`, renders via `renderToReadableStream` and collects individual\n * chunks. When `false` (default), uses `renderToString` for a single\n * synchronous HTML output.\n */\n readonly streaming?: boolean;\n}\n\n/**\n * The result of rendering a React Server Component via\n * {@link RscTestRuntime.renderServerComponent}.\n */\nexport interface RscRenderResult {\n /** The complete HTML string produced by the render. */\n readonly html: string;\n /**\n * A cloned `ReadableStream` of the raw bytes. Only present when the runtime\n * was created with `streaming: true`; otherwise `null`.\n */\n readonly stream: ReadableStream<Uint8Array> | null;\n /**\n * Decoded text chunks collected from the stream. Empty when `streaming` is\n * `false`.\n */\n readonly chunks: readonly string[];\n}\n\n/**\n * Extended test runtime that adds React Server Component rendering on top of\n * the base {@link StartTestRuntime}.\n *\n * @remarks\n * Created by {@link createRscTestRuntime}. Inherits all members from\n * {@link StartTestRuntime} and adds {@link renderServerComponent}.\n */\nexport interface RscTestRuntime extends StartTestRuntime {\n /**\n * Render a React Server Component to HTML.\n *\n * @typeParam TProps - The component's props type.\n * @param component - The React component to render.\n * @param props - Props forwarded to `createElement(component, props)`.\n * @returns A `Promise` resolving to an {@link RscRenderResult} containing the\n * rendered HTML and, when streaming is enabled, the raw stream and decoded\n * chunks.\n */\n readonly renderServerComponent: <TProps extends Record<string, unknown>>(component: ComponentType<TProps>, props: TProps) => Promise<RscRenderResult>;\n}\n\n/**\n * Create an {@link RscTestRuntime} for rendering React Server Components in a\n * simulated TanStack Start environment.\n *\n * @param options - Runtime configuration. See {@link RscTestRuntimeOptions}.\n * @returns A `Promise` resolving to an {@link RscTestRuntime} instance.\n *\n * @example\n * ```ts\n * import { createRscTestRuntime } from '@tanstack-router-testing/react-start-testing';\n *\n * const runtime = await createRscTestRuntime({ streaming: true });\n *\n * function Greeting({ name }: { name: string }) {\n * return <h1>Hello, {name}!</h1>;\n * }\n *\n * const { html, chunks } = await runtime.renderServerComponent(Greeting, {\n * name: 'TanStack',\n * });\n * // html === '<h1>Hello, TanStack!</h1>'\n *\n * runtime.cleanup();\n * ```\n *\n * @remarks\n * Delegates to {@link createStartTestRuntime} for the base runtime, then layers\n * on `renderServerComponent` which uses `react-dom/server` under the hood. Set\n * `streaming: true` in options to render via `renderToReadableStream` instead of\n * the default `renderToString`.\n */\nexport const createRscTestRuntime = async (options: RscTestRuntimeOptions = {}): Promise<RscTestRuntime> => {\n const base = await createStartTestRuntime(options);\n const streaming = options.streaming ?? false;\n\n return {\n ...base,\n renderServerComponent: async <TProps extends Record<string, unknown>>(component: ComponentType<TProps>, props: TProps): Promise<RscRenderResult> => {\n const element = createElement(component, props);\n\n if (!streaming) {\n const html = renderToString(element);\n return { html, stream: null, chunks: [] };\n }\n\n const stream = await renderToReadableStream(element);\n const chunks: string[] = [];\n const decoder = new TextDecoder();\n\n const [collectStream, returnStream] = stream.tee();\n\n const reader = collectStream.getReader();\n const collectChunks = async (): Promise<void> => {\n const result = await reader.read();\n if (result.value !== undefined) {\n chunks.push(decoder.decode(result.value, { stream: !result.done }));\n }\n if (!result.done) await collectChunks();\n };\n await collectChunks();\n\n const html = chunks.join('');\n return { html, stream: returnStream, chunks };\n },\n };\n};\n","/**\n * Upstream-shaped test helpers for `@tanstack/react-start`.\n *\n * Server functions are called directly in tests, exactly as production code\n * calls them. This package only exposes mock and environment controls.\n */\n\nexport { type CallMiddlewareOptions, type CallMiddlewareResult, callMiddleware } from '@tanstack-router-testing/router-testing-core';\nexport { clearStartMocks } from './clearStartMocks.ts';\nexport { type AnyServerFn, mockServerFn, type ServerFnMock } from './mockServerFn.ts';\nexport { type MockMiddlewareOptions, mockMiddleware } from './mockMiddleware.ts';\nexport { runInStartEnv } from './isomorphic.ts';\nexport { createRscTestRuntime, type RscRenderResult, type RscTestRuntime, type RscTestRuntimeOptions } from './rsc.tsx';\nexport { createStartTestRuntime, type StartTestRuntime, type StartTestRuntimeOptions, type StartTestRunOptions } from './runtime.ts';\n\n/**\n * Current package version. Bumped at release time.\n */\nexport const VERSION = '0.0.0';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { clearAllMiddlewareMocks, clearAllServerFnMocks, runInEnv, setMiddlewareMock, setServerFnMock } from "@tanstack-router-testing/router-testing-core";
|
|
2
|
+
//#region src/clearStartMocks.ts
|
|
3
|
+
/**
|
|
4
|
+
* Clear every server-function and middleware mock installed by
|
|
5
|
+
* {@link mockServerFn} or {@link mockMiddleware}.
|
|
6
|
+
*
|
|
7
|
+
* @returns `void`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { afterEach } from 'vitest';
|
|
12
|
+
* import { clearStartMocks } from '@tanstack-router-testing/react-start-testing';
|
|
13
|
+
*
|
|
14
|
+
* afterEach(() => {
|
|
15
|
+
* clearStartMocks();
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* This is the same function wired to {@link StartTestRuntime.cleanup}, so you
|
|
21
|
+
* only need to call it explicitly when installing mocks outside of a runtime
|
|
22
|
+
* (i.e. via {@link mockServerFn} / {@link mockMiddleware} directly).
|
|
23
|
+
*/
|
|
24
|
+
const clearStartMocks = () => {
|
|
25
|
+
clearAllServerFnMocks();
|
|
26
|
+
clearAllMiddlewareMocks();
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/mockServerFn.ts
|
|
30
|
+
const hasKey = (value, key) => typeof value === "object" && value !== null && key in value;
|
|
31
|
+
const toCallableOptions = (ctx) => {
|
|
32
|
+
if (!hasKey(ctx, "data")) return ctx;
|
|
33
|
+
const source = ctx;
|
|
34
|
+
return {
|
|
35
|
+
data: source.data,
|
|
36
|
+
...source.headers !== void 0 ? { headers: source.headers } : {},
|
|
37
|
+
...source.signal !== void 0 ? { signal: source.signal } : {},
|
|
38
|
+
...source.fetch !== void 0 ? { fetch: source.fetch } : {}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Install a mock implementation for a TanStack Start server function.
|
|
43
|
+
*
|
|
44
|
+
* @param fn - The server function created by `createServerFn().handler(...)`.
|
|
45
|
+
* @param impl - A {@link ServerFnMock} that replaces the real handler for the
|
|
46
|
+
* duration of the test. It receives the same callable-shape arguments (e.g.
|
|
47
|
+
* `{ data }`) as the original function.
|
|
48
|
+
* @returns A disposer function that restores the original implementation when
|
|
49
|
+
* called. Alternatively, call {@link clearStartMocks} to remove all mocks at
|
|
50
|
+
* once.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { createServerFn } from '@tanstack/react-start';
|
|
55
|
+
* import { mockServerFn } from '@tanstack-router-testing/react-start-testing';
|
|
56
|
+
*
|
|
57
|
+
* const listOrders = createServerFn()
|
|
58
|
+
* .validator((input: { userId: string }) => input)
|
|
59
|
+
* .handler(async ({ data }) => db.orders.findMany(data.userId));
|
|
60
|
+
*
|
|
61
|
+
* const dispose = mockServerFn(listOrders, async ({ data }) => [
|
|
62
|
+
* { id: '1', userId: data.userId, total: 42 },
|
|
63
|
+
* ]);
|
|
64
|
+
*
|
|
65
|
+
* // ... run your test ...
|
|
66
|
+
* dispose();
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* The mock is authored against the public callable shape, so a server function
|
|
71
|
+
* normally called as `listOrders({ data })` is mocked with that same signature.
|
|
72
|
+
* Internal context fields are normalised automatically before reaching the mock.
|
|
73
|
+
*/
|
|
74
|
+
const mockServerFn = (fn, impl) => {
|
|
75
|
+
const handler = (ctx) => impl(toCallableOptions(ctx));
|
|
76
|
+
return setServerFnMock(fn, handler);
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/mockMiddleware.ts
|
|
80
|
+
/**
|
|
81
|
+
* Override one or both phases of a registered middleware.
|
|
82
|
+
*
|
|
83
|
+
* @param mw - The middleware object returned by
|
|
84
|
+
* `createMiddleware().server(...).client(...)`.
|
|
85
|
+
* @param options - A {@link MockMiddlewareOptions} object specifying which
|
|
86
|
+
* phases to replace.
|
|
87
|
+
* @returns A disposer function that restores the original middleware handlers.
|
|
88
|
+
* Alternatively, call {@link clearStartMocks} to remove all mocks at once.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* import { createMiddleware } from '@tanstack/react-start';
|
|
93
|
+
* import { mockMiddleware } from '@tanstack-router-testing/react-start-testing';
|
|
94
|
+
*
|
|
95
|
+
* const authMiddleware = createMiddleware()
|
|
96
|
+
* .server(async ({ next }) => next({ context: { user: await getUser() } }))
|
|
97
|
+
* .client(async ({ next }) => next());
|
|
98
|
+
*
|
|
99
|
+
* const dispose = mockMiddleware(authMiddleware, {
|
|
100
|
+
* server: async ({ next }) => next({ context: { user: { id: 'test-user' } } }),
|
|
101
|
+
* });
|
|
102
|
+
*
|
|
103
|
+
* // ... run your test ...
|
|
104
|
+
* dispose();
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @throws If `mw` is not registered. Registration is the shim's
|
|
108
|
+
* responsibility (see ADR 0001).
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* Server functions are invoked directly and mocked middleware participates in
|
|
112
|
+
* that normal call path. Only the phases you specify in `options` are replaced;
|
|
113
|
+
* the rest continue to run their real implementations.
|
|
114
|
+
*/
|
|
115
|
+
const mockMiddleware = (mw, options) => setMiddlewareMock(mw, options);
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/isomorphic.ts
|
|
118
|
+
/**
|
|
119
|
+
* Execute `fn` with the simulated TanStack Start environment forced to `env`,
|
|
120
|
+
* then restore the prior value.
|
|
121
|
+
*
|
|
122
|
+
* @typeParam T - The return type of `fn`.
|
|
123
|
+
* @param env - The environment to simulate: `'server'` or `'client'`.
|
|
124
|
+
* @param fn - A synchronous or asynchronous function to run inside the
|
|
125
|
+
* simulated environment.
|
|
126
|
+
* @returns A `Promise` resolving to the return value of `fn`.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* import { runInStartEnv } from '@tanstack-router-testing/react-start-testing';
|
|
131
|
+
*
|
|
132
|
+
* const result = await runInStartEnv('server', () => {
|
|
133
|
+
* // Code here sees `import.meta.env.SSR === true`
|
|
134
|
+
* return fetchDataOnServer();
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @remarks
|
|
139
|
+
* The environment is scoped to the execution of `fn` and is restored
|
|
140
|
+
* automatically even if `fn` throws. Used internally by
|
|
141
|
+
* {@link createStartTestRuntime} to set the environment for each
|
|
142
|
+
* {@link StartTestRuntime.run | run} invocation.
|
|
143
|
+
*/
|
|
144
|
+
const runInStartEnv = async (env, fn) => runInEnv(env, fn);
|
|
145
|
+
//#endregion
|
|
146
|
+
export { clearStartMocks as i, mockMiddleware as n, mockServerFn as r, runInStartEnv as t };
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=isomorphic-Bw5L_zk1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isomorphic-Bw5L_zk1.mjs","names":[],"sources":["../src/clearStartMocks.ts","../src/mockServerFn.ts","../src/mockMiddleware.ts","../src/isomorphic.ts"],"sourcesContent":["import { clearAllMiddlewareMocks, clearAllServerFnMocks } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Clear every server-function and middleware mock installed by\n * {@link mockServerFn} or {@link mockMiddleware}.\n *\n * @returns `void`.\n *\n * @example\n * ```ts\n * import { afterEach } from 'vitest';\n * import { clearStartMocks } from '@tanstack-router-testing/react-start-testing';\n *\n * afterEach(() => {\n * clearStartMocks();\n * });\n * ```\n *\n * @remarks\n * This is the same function wired to {@link StartTestRuntime.cleanup}, so you\n * only need to call it explicitly when installing mocks outside of a runtime\n * (i.e. via {@link mockServerFn} / {@link mockMiddleware} directly).\n */\nexport const clearStartMocks = (): void => {\n clearAllServerFnMocks();\n clearAllMiddlewareMocks();\n};\n","import type { AnyFn } from '@tanstack-router-testing/router-testing-core';\n\nimport { setServerFnMock } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Catch-all type representing any TanStack Start server function.\n *\n * @remarks\n * Used as a generic constraint in {@link mockServerFn} and {@link ServerFnMock}\n * to accept any function created by `createServerFn().handler(...)`.\n */\nexport type AnyServerFn = (...args: never[]) => unknown;\n\n/**\n * The mock implementation signature for a server function of type `TFn`.\n *\n * @typeParam TFn - The server function type being mocked.\n *\n * @remarks\n * The mock receives the same callable-shape arguments as the real server\n * function (e.g. `{ data }`) and must return a compatible result. Full generic\n * inference is preserved so autocomplete works identically to the real call.\n *\n * @see {@link mockServerFn}\n */\nexport type ServerFnMock<TFn extends AnyServerFn> = (...args: Parameters<TFn>) => ReturnType<TFn>;\n\nconst hasKey = (value: unknown, key: string): boolean => typeof value === 'object' && value !== null && key in value;\n\nconst toCallableOptions = (ctx: unknown): unknown => {\n if (!hasKey(ctx, 'data')) return ctx;\n\n const source = ctx as {\n readonly data?: unknown;\n readonly headers?: HeadersInit;\n readonly signal?: AbortSignal;\n readonly fetch?: typeof globalThis.fetch;\n };\n\n return {\n data: source.data,\n ...(source.headers !== undefined ? { headers: source.headers } : {}),\n ...(source.signal !== undefined ? { signal: source.signal } : {}),\n ...(source.fetch !== undefined ? { fetch: source.fetch } : {}),\n };\n};\n\n/**\n * Install a mock implementation for a TanStack Start server function.\n *\n * @param fn - The server function created by `createServerFn().handler(...)`.\n * @param impl - A {@link ServerFnMock} that replaces the real handler for the\n * duration of the test. It receives the same callable-shape arguments (e.g.\n * `{ data }`) as the original function.\n * @returns A disposer function that restores the original implementation when\n * called. Alternatively, call {@link clearStartMocks} to remove all mocks at\n * once.\n *\n * @example\n * ```ts\n * import { createServerFn } from '@tanstack/react-start';\n * import { mockServerFn } from '@tanstack-router-testing/react-start-testing';\n *\n * const listOrders = createServerFn()\n * .validator((input: { userId: string }) => input)\n * .handler(async ({ data }) => db.orders.findMany(data.userId));\n *\n * const dispose = mockServerFn(listOrders, async ({ data }) => [\n * { id: '1', userId: data.userId, total: 42 },\n * ]);\n *\n * // ... run your test ...\n * dispose();\n * ```\n *\n * @remarks\n * The mock is authored against the public callable shape, so a server function\n * normally called as `listOrders({ data })` is mocked with that same signature.\n * Internal context fields are normalised automatically before reaching the mock.\n */\nexport const mockServerFn = <TFn extends AnyServerFn>(fn: TFn, impl: ServerFnMock<TFn>): (() => void) => {\n const handler: AnyFn = (ctx?: unknown) => (impl as AnyFn)(toCallableOptions(ctx));\n return setServerFnMock(fn as unknown as AnyFn, handler);\n};\n","import type { AnyFn } from '@tanstack-router-testing/router-testing-core';\n\nimport { setMiddlewareMock } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Phase override options for {@link mockMiddleware}.\n *\n * @remarks\n * Provide `client`, `server`, or both. Omitted keys leave the corresponding\n * phase untouched, so you can mock only the server side without affecting the\n * client phase and vice-versa.\n */\nexport interface MockMiddlewareOptions {\n /** Override for the `.client()` phase. When omitted the real client handler runs. */\n readonly client?: AnyFn;\n /** Override for the `.server()` phase. When omitted the real server handler runs. */\n readonly server?: AnyFn;\n}\n\n/**\n * Override one or both phases of a registered middleware.\n *\n * @param mw - The middleware object returned by\n * `createMiddleware().server(...).client(...)`.\n * @param options - A {@link MockMiddlewareOptions} object specifying which\n * phases to replace.\n * @returns A disposer function that restores the original middleware handlers.\n * Alternatively, call {@link clearStartMocks} to remove all mocks at once.\n *\n * @example\n * ```ts\n * import { createMiddleware } from '@tanstack/react-start';\n * import { mockMiddleware } from '@tanstack-router-testing/react-start-testing';\n *\n * const authMiddleware = createMiddleware()\n * .server(async ({ next }) => next({ context: { user: await getUser() } }))\n * .client(async ({ next }) => next());\n *\n * const dispose = mockMiddleware(authMiddleware, {\n * server: async ({ next }) => next({ context: { user: { id: 'test-user' } } }),\n * });\n *\n * // ... run your test ...\n * dispose();\n * ```\n *\n * @throws If `mw` is not registered. Registration is the shim's\n * responsibility (see ADR 0001).\n *\n * @remarks\n * Server functions are invoked directly and mocked middleware participates in\n * that normal call path. Only the phases you specify in `options` are replaced;\n * the rest continue to run their real implementations.\n */\nexport const mockMiddleware = (mw: object, options: MockMiddlewareOptions): (() => void) => setMiddlewareMock(mw, options);\n","import type { TestEnv } from '@tanstack-router-testing/router-testing-core';\n\nimport { runInEnv } from '@tanstack-router-testing/router-testing-core';\n\n/**\n * Execute `fn` with the simulated TanStack Start environment forced to `env`,\n * then restore the prior value.\n *\n * @typeParam T - The return type of `fn`.\n * @param env - The environment to simulate: `'server'` or `'client'`.\n * @param fn - A synchronous or asynchronous function to run inside the\n * simulated environment.\n * @returns A `Promise` resolving to the return value of `fn`.\n *\n * @example\n * ```ts\n * import { runInStartEnv } from '@tanstack-router-testing/react-start-testing';\n *\n * const result = await runInStartEnv('server', () => {\n * // Code here sees `import.meta.env.SSR === true`\n * return fetchDataOnServer();\n * });\n * ```\n *\n * @remarks\n * The environment is scoped to the execution of `fn` and is restored\n * automatically even if `fn` throws. Used internally by\n * {@link createStartTestRuntime} to set the environment for each\n * {@link StartTestRuntime.run | run} invocation.\n */\nexport const runInStartEnv = async <T>(env: TestEnv, fn: () => T | Promise<T>): Promise<T> => runInEnv(env, fn);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,wBAA8B;AACzC,wBAAuB;AACvB,0BAAyB;;;;ACE3B,MAAM,UAAU,OAAgB,QAAyB,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAO;AAE/G,MAAM,qBAAqB,QAA0B;AACnD,KAAI,CAAC,OAAO,KAAK,OAAO,CAAE,QAAO;CAEjC,MAAM,SAAS;AAOf,QAAO;EACL,MAAM,OAAO;EACb,GAAI,OAAO,YAAY,KAAA,IAAY,EAAE,SAAS,OAAO,SAAS,GAAG,EAAE;EACnE,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;EAChE,GAAI,OAAO,UAAU,KAAA,IAAY,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;EAC9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCH,MAAa,gBAAyC,IAAS,SAA0C;CACvG,MAAM,WAAkB,QAAmB,KAAe,kBAAkB,IAAI,CAAC;AACjF,QAAO,gBAAgB,IAAwB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5BzD,MAAa,kBAAkB,IAAY,YAAiD,kBAAkB,IAAI,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxB1H,MAAa,gBAAgB,OAAU,KAAc,OAAyC,SAAS,KAAK,GAAG"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { AnyFn, TestEnv } from "@tanstack-router-testing/router-testing-core";
|
|
2
|
+
|
|
3
|
+
//#region src/clearStartMocks.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Clear every server-function and middleware mock installed by
|
|
6
|
+
* {@link mockServerFn} or {@link mockMiddleware}.
|
|
7
|
+
*
|
|
8
|
+
* @returns `void`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { afterEach } from 'vitest';
|
|
13
|
+
* import { clearStartMocks } from '@tanstack-router-testing/react-start-testing';
|
|
14
|
+
*
|
|
15
|
+
* afterEach(() => {
|
|
16
|
+
* clearStartMocks();
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* This is the same function wired to {@link StartTestRuntime.cleanup}, so you
|
|
22
|
+
* only need to call it explicitly when installing mocks outside of a runtime
|
|
23
|
+
* (i.e. via {@link mockServerFn} / {@link mockMiddleware} directly).
|
|
24
|
+
*/
|
|
25
|
+
declare const clearStartMocks: () => void;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/mockServerFn.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Catch-all type representing any TanStack Start server function.
|
|
30
|
+
*
|
|
31
|
+
* @remarks
|
|
32
|
+
* Used as a generic constraint in {@link mockServerFn} and {@link ServerFnMock}
|
|
33
|
+
* to accept any function created by `createServerFn().handler(...)`.
|
|
34
|
+
*/
|
|
35
|
+
type AnyServerFn = (...args: never[]) => unknown;
|
|
36
|
+
/**
|
|
37
|
+
* The mock implementation signature for a server function of type `TFn`.
|
|
38
|
+
*
|
|
39
|
+
* @typeParam TFn - The server function type being mocked.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* The mock receives the same callable-shape arguments as the real server
|
|
43
|
+
* function (e.g. `{ data }`) and must return a compatible result. Full generic
|
|
44
|
+
* inference is preserved so autocomplete works identically to the real call.
|
|
45
|
+
*
|
|
46
|
+
* @see {@link mockServerFn}
|
|
47
|
+
*/
|
|
48
|
+
type ServerFnMock<TFn extends AnyServerFn> = (...args: Parameters<TFn>) => ReturnType<TFn>;
|
|
49
|
+
/**
|
|
50
|
+
* Install a mock implementation for a TanStack Start server function.
|
|
51
|
+
*
|
|
52
|
+
* @param fn - The server function created by `createServerFn().handler(...)`.
|
|
53
|
+
* @param impl - A {@link ServerFnMock} that replaces the real handler for the
|
|
54
|
+
* duration of the test. It receives the same callable-shape arguments (e.g.
|
|
55
|
+
* `{ data }`) as the original function.
|
|
56
|
+
* @returns A disposer function that restores the original implementation when
|
|
57
|
+
* called. Alternatively, call {@link clearStartMocks} to remove all mocks at
|
|
58
|
+
* once.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { createServerFn } from '@tanstack/react-start';
|
|
63
|
+
* import { mockServerFn } from '@tanstack-router-testing/react-start-testing';
|
|
64
|
+
*
|
|
65
|
+
* const listOrders = createServerFn()
|
|
66
|
+
* .validator((input: { userId: string }) => input)
|
|
67
|
+
* .handler(async ({ data }) => db.orders.findMany(data.userId));
|
|
68
|
+
*
|
|
69
|
+
* const dispose = mockServerFn(listOrders, async ({ data }) => [
|
|
70
|
+
* { id: '1', userId: data.userId, total: 42 },
|
|
71
|
+
* ]);
|
|
72
|
+
*
|
|
73
|
+
* // ... run your test ...
|
|
74
|
+
* dispose();
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* The mock is authored against the public callable shape, so a server function
|
|
79
|
+
* normally called as `listOrders({ data })` is mocked with that same signature.
|
|
80
|
+
* Internal context fields are normalised automatically before reaching the mock.
|
|
81
|
+
*/
|
|
82
|
+
declare const mockServerFn: <TFn extends AnyServerFn>(fn: TFn, impl: ServerFnMock<TFn>) => (() => void);
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/mockMiddleware.d.ts
|
|
85
|
+
/**
|
|
86
|
+
* Phase override options for {@link mockMiddleware}.
|
|
87
|
+
*
|
|
88
|
+
* @remarks
|
|
89
|
+
* Provide `client`, `server`, or both. Omitted keys leave the corresponding
|
|
90
|
+
* phase untouched, so you can mock only the server side without affecting the
|
|
91
|
+
* client phase and vice-versa.
|
|
92
|
+
*/
|
|
93
|
+
interface MockMiddlewareOptions {
|
|
94
|
+
/** Override for the `.client()` phase. When omitted the real client handler runs. */
|
|
95
|
+
readonly client?: AnyFn;
|
|
96
|
+
/** Override for the `.server()` phase. When omitted the real server handler runs. */
|
|
97
|
+
readonly server?: AnyFn;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Override one or both phases of a registered middleware.
|
|
101
|
+
*
|
|
102
|
+
* @param mw - The middleware object returned by
|
|
103
|
+
* `createMiddleware().server(...).client(...)`.
|
|
104
|
+
* @param options - A {@link MockMiddlewareOptions} object specifying which
|
|
105
|
+
* phases to replace.
|
|
106
|
+
* @returns A disposer function that restores the original middleware handlers.
|
|
107
|
+
* Alternatively, call {@link clearStartMocks} to remove all mocks at once.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { createMiddleware } from '@tanstack/react-start';
|
|
112
|
+
* import { mockMiddleware } from '@tanstack-router-testing/react-start-testing';
|
|
113
|
+
*
|
|
114
|
+
* const authMiddleware = createMiddleware()
|
|
115
|
+
* .server(async ({ next }) => next({ context: { user: await getUser() } }))
|
|
116
|
+
* .client(async ({ next }) => next());
|
|
117
|
+
*
|
|
118
|
+
* const dispose = mockMiddleware(authMiddleware, {
|
|
119
|
+
* server: async ({ next }) => next({ context: { user: { id: 'test-user' } } }),
|
|
120
|
+
* });
|
|
121
|
+
*
|
|
122
|
+
* // ... run your test ...
|
|
123
|
+
* dispose();
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @throws If `mw` is not registered. Registration is the shim's
|
|
127
|
+
* responsibility (see ADR 0001).
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* Server functions are invoked directly and mocked middleware participates in
|
|
131
|
+
* that normal call path. Only the phases you specify in `options` are replaced;
|
|
132
|
+
* the rest continue to run their real implementations.
|
|
133
|
+
*/
|
|
134
|
+
declare const mockMiddleware: (mw: object, options: MockMiddlewareOptions) => (() => void);
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/isomorphic.d.ts
|
|
137
|
+
/**
|
|
138
|
+
* Execute `fn` with the simulated TanStack Start environment forced to `env`,
|
|
139
|
+
* then restore the prior value.
|
|
140
|
+
*
|
|
141
|
+
* @typeParam T - The return type of `fn`.
|
|
142
|
+
* @param env - The environment to simulate: `'server'` or `'client'`.
|
|
143
|
+
* @param fn - A synchronous or asynchronous function to run inside the
|
|
144
|
+
* simulated environment.
|
|
145
|
+
* @returns A `Promise` resolving to the return value of `fn`.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* import { runInStartEnv } from '@tanstack-router-testing/react-start-testing';
|
|
150
|
+
*
|
|
151
|
+
* const result = await runInStartEnv('server', () => {
|
|
152
|
+
* // Code here sees `import.meta.env.SSR === true`
|
|
153
|
+
* return fetchDataOnServer();
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @remarks
|
|
158
|
+
* The environment is scoped to the execution of `fn` and is restored
|
|
159
|
+
* automatically even if `fn` throws. Used internally by
|
|
160
|
+
* {@link createStartTestRuntime} to set the environment for each
|
|
161
|
+
* {@link StartTestRuntime.run | run} invocation.
|
|
162
|
+
*/
|
|
163
|
+
declare const runInStartEnv: <T>(env: TestEnv, fn: () => T | Promise<T>) => Promise<T>;
|
|
164
|
+
//#endregion
|
|
165
|
+
export { ServerFnMock as a, AnyServerFn as i, MockMiddlewareOptions as n, mockServerFn as o, mockMiddleware as r, clearStartMocks as s, runInStartEnv as t };
|
|
166
|
+
//# sourceMappingURL=isomorphic-DiwceaLg.d.mts.map
|
|
@@ -483,4 +483,4 @@ function useServerFn(serverFn) {
|
|
|
483
483
|
//#endregion
|
|
484
484
|
export { createServerFn$1 as a, useServerFn as c, createMiddleware$1 as i, createClientOnlyFn as n, createServerOnlyFn as o, createIsomorphicFn as r, createStart$1 as s, __setStartOptionsForTesting as t };
|
|
485
485
|
|
|
486
|
-
//# sourceMappingURL=shim-
|
|
486
|
+
//# sourceMappingURL=shim-C-PA0sYH.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shim-DR16QaLL.mjs","names":["createServerFn","createMiddleware","createStart"],"sources":["../../../node_modules/.pnpm/@tanstack+router-core@1.168.16/node_modules/@tanstack/router-core/dist/esm/redirect.js","../../../node_modules/.pnpm/cookie-es@3.1.1/node_modules/cookie-es/dist/index.mjs","../../../node_modules/.pnpm/@tanstack+router-core@1.168.16/node_modules/@tanstack/router-core/dist/esm/ssr/headers.js","../src/shim.ts"],"sourcesContent":["//#region src/redirect.ts\n/**\n* Create a redirect Response understood by TanStack Router.\n*\n* Use from route `loader`/`beforeLoad` or server functions to trigger a\n* navigation. If `throw: true` is set, the redirect is thrown instead of\n* returned. When an absolute `href` is supplied and `reloadDocument` is not\n* set, a full-document navigation is inferred.\n*\n* @param opts Options for the redirect. Common fields:\n* - `href`: absolute URL for external redirects; infers `reloadDocument`.\n* - `statusCode`: HTTP status code to use (defaults to 307).\n* - `headers`: additional headers to include on the Response.\n* - Standard navigation options like `to`, `params`, `search`, `replace`,\n* and `reloadDocument` for internal redirects.\n* @returns A Response augmented with router navigation options.\n* @link https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction\n*/\nfunction redirect(opts) {\n\topts.statusCode = opts.statusCode || opts.code || 307;\n\tif (!opts._builtLocation && !opts.reloadDocument && typeof opts.href === \"string\") try {\n\t\tnew URL(opts.href);\n\t\topts.reloadDocument = true;\n\t} catch {}\n\tconst headers = new Headers(opts.headers);\n\tif (opts.href && headers.get(\"Location\") === null) headers.set(\"Location\", opts.href);\n\tconst response = new Response(null, {\n\t\tstatus: opts.statusCode,\n\t\theaders\n\t});\n\tresponse.options = opts;\n\tif (opts.throw) throw response;\n\treturn response;\n}\n/** Check whether a value is a TanStack Router redirect Response. */\n/** Check whether a value is a TanStack Router redirect Response. */\nfunction isRedirect(obj) {\n\treturn obj instanceof Response && !!obj.options;\n}\n/** True if value is a redirect with a resolved `href` location. */\n/** True if value is a redirect with a resolved `href` location. */\nfunction isResolvedRedirect(obj) {\n\treturn isRedirect(obj) && !!obj.options.href;\n}\n/** Parse a serialized redirect object back into a redirect Response. */\n/** Parse a serialized redirect object back into a redirect Response. */\nfunction parseRedirect(obj) {\n\tif (obj !== null && typeof obj === \"object\" && obj.isSerializedRedirect) return redirect(obj);\n}\n//#endregion\nexport { isRedirect, isResolvedRedirect, parseRedirect, redirect };\n\n//# sourceMappingURL=redirect.js.map","const COOKIE_MAX_AGE_LIMIT = 3456e4;\nfunction endIndex(str, min, len) {\n\tconst index = str.indexOf(\";\", min);\n\treturn index === -1 ? len : index;\n}\nfunction eqIndex(str, min, max) {\n\tconst index = str.indexOf(\"=\", min);\n\treturn index < max ? index : -1;\n}\nfunction valueSlice(str, min, max) {\n\tif (min === max) return \"\";\n\tlet start = min;\n\tlet end = max;\n\tdo {\n\t\tconst code = str.charCodeAt(start);\n\t\tif (code !== 32 && code !== 9) break;\n\t} while (++start < end);\n\twhile (end > start) {\n\t\tconst code = str.charCodeAt(end - 1);\n\t\tif (code !== 32 && code !== 9) break;\n\t\tend--;\n\t}\n\treturn str.slice(start, end);\n}\nconst NullObject = /* @__PURE__ */ (() => {\n\tconst C = function() {};\n\tC.prototype = Object.create(null);\n\treturn C;\n})();\nfunction parse(str, options) {\n\tconst obj = new NullObject();\n\tconst len = str.length;\n\tif (len < 2) return obj;\n\tconst dec = options?.decode || decode;\n\tconst allowMultiple = options?.allowMultiple || false;\n\tlet index = 0;\n\tdo {\n\t\tconst eqIdx = eqIndex(str, index, len);\n\t\tif (eqIdx === -1) break;\n\t\tconst endIdx = endIndex(str, index, len);\n\t\tif (eqIdx > endIdx) {\n\t\t\tindex = str.lastIndexOf(\";\", eqIdx - 1) + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = valueSlice(str, index, eqIdx);\n\t\tif (options?.filter && !options.filter(key)) {\n\t\t\tindex = endIdx + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst val = dec(valueSlice(str, eqIdx + 1, endIdx));\n\t\tif (allowMultiple) {\n\t\t\tconst existing = obj[key];\n\t\t\tif (existing === void 0) obj[key] = val;\n\t\t\telse if (Array.isArray(existing)) existing.push(val);\n\t\t\telse obj[key] = [existing, val];\n\t\t} else if (obj[key] === void 0) obj[key] = val;\n\t\tindex = endIdx + 1;\n\t} while (index < len);\n\treturn obj;\n}\nfunction decode(str) {\n\tif (!str.includes(\"%\")) return str;\n\ttry {\n\t\treturn decodeURIComponent(str);\n\t} catch {\n\t\treturn str;\n\t}\n}\nconst cookieNameRegExp = /^[\\u0021-\\u003A\\u003C\\u003E-\\u007E]+$/;\nconst cookieValueRegExp = /^[\\u0021-\\u003A\\u003C-\\u007E]*$/;\nconst domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;\nconst pathValueRegExp = /^[\\u0020-\\u003A\\u003C-\\u007E]*$/;\nconst __toString = Object.prototype.toString;\nfunction stringifyCookie(cookie, options) {\n\tconst enc = options?.encode || encodeURIComponent;\n\tconst keys = Object.keys(cookie);\n\tlet str = \"\";\n\tfor (const [i, name] of keys.entries()) {\n\t\tconst val = cookie[name];\n\t\tif (val === void 0) continue;\n\t\tif (!cookieNameRegExp.test(name)) throw new TypeError(`cookie name is invalid: ${name}`);\n\t\tconst value = enc(val);\n\t\tif (!cookieValueRegExp.test(value)) throw new TypeError(`cookie val is invalid: ${val}`);\n\t\tif (i > 0) str += \"; \";\n\t\tstr += name + \"=\" + value;\n\t}\n\treturn str;\n}\nfunction serialize(_a0, _a1, _a2) {\n\tconst isObj = typeof _a0 === \"object\" && _a0 !== null;\n\tconst options = isObj ? _a1 : _a2;\n\tconst stringify = options?.stringify || JSON.stringify;\n\tconst cookie = isObj ? _a0 : {\n\t\t..._a2,\n\t\tname: _a0,\n\t\tvalue: _a1 == void 0 ? \"\" : typeof _a1 === \"string\" ? _a1 : stringify(_a1)\n\t};\n\tconst enc = options?.encode || encodeURIComponent;\n\tif (!cookieNameRegExp.test(cookie.name)) throw new TypeError(`argument name is invalid: ${cookie.name}`);\n\tconst value = cookie.value ? enc(cookie.value) : \"\";\n\tif (!cookieValueRegExp.test(value)) throw new TypeError(`argument val is invalid: ${cookie.value}`);\n\tif (!cookie.secure) {\n\t\tif (cookie.partitioned) throw new TypeError(`Partitioned cookies must have the Secure attribute`);\n\t\tif (cookie.sameSite && String(cookie.sameSite).toLowerCase() === \"none\") throw new TypeError(`SameSite=None cookies must have the Secure attribute`);\n\t\tif (cookie.name.length > 9 && cookie.name.charCodeAt(0) === 95 && cookie.name.charCodeAt(1) === 95) {\n\t\t\tconst nameLower = cookie.name.toLowerCase();\n\t\t\tif (nameLower.startsWith(\"__secure-\") || nameLower.startsWith(\"__host-\")) throw new TypeError(`${cookie.name} cookies must have the Secure attribute`);\n\t\t}\n\t}\n\tif (cookie.name.length > 7 && cookie.name.charCodeAt(0) === 95 && cookie.name.charCodeAt(1) === 95 && cookie.name.toLowerCase().startsWith(\"__host-\")) {\n\t\tif (cookie.path !== \"/\") throw new TypeError(`__Host- cookies must have Path=/`);\n\t\tif (cookie.domain) throw new TypeError(`__Host- cookies must not have a Domain attribute`);\n\t}\n\tlet str = cookie.name + \"=\" + value;\n\tif (cookie.maxAge !== void 0) {\n\t\tif (!Number.isInteger(cookie.maxAge)) throw new TypeError(`option maxAge is invalid: ${cookie.maxAge}`);\n\t\tstr += \"; Max-Age=\" + Math.max(0, Math.min(cookie.maxAge, COOKIE_MAX_AGE_LIMIT));\n\t}\n\tif (cookie.domain) {\n\t\tif (!domainValueRegExp.test(cookie.domain)) throw new TypeError(`option domain is invalid: ${cookie.domain}`);\n\t\tstr += \"; Domain=\" + cookie.domain;\n\t}\n\tif (cookie.path) {\n\t\tif (!pathValueRegExp.test(cookie.path)) throw new TypeError(`option path is invalid: ${cookie.path}`);\n\t\tstr += \"; Path=\" + cookie.path;\n\t}\n\tif (cookie.expires) {\n\t\tif (!isDate(cookie.expires) || !Number.isFinite(cookie.expires.valueOf())) throw new TypeError(`option expires is invalid: ${cookie.expires}`);\n\t\tstr += \"; Expires=\" + cookie.expires.toUTCString();\n\t}\n\tif (cookie.httpOnly) str += \"; HttpOnly\";\n\tif (cookie.secure) str += \"; Secure\";\n\tif (cookie.partitioned) str += \"; Partitioned\";\n\tif (cookie.priority) switch (typeof cookie.priority === \"string\" ? cookie.priority.toLowerCase() : void 0) {\n\t\tcase \"low\":\n\t\t\tstr += \"; Priority=Low\";\n\t\t\tbreak;\n\t\tcase \"medium\":\n\t\t\tstr += \"; Priority=Medium\";\n\t\t\tbreak;\n\t\tcase \"high\":\n\t\t\tstr += \"; Priority=High\";\n\t\t\tbreak;\n\t\tdefault: throw new TypeError(`option priority is invalid: ${cookie.priority}`);\n\t}\n\tif (cookie.sameSite) switch (typeof cookie.sameSite === \"string\" ? cookie.sameSite.toLowerCase() : cookie.sameSite) {\n\t\tcase true:\n\t\tcase \"strict\":\n\t\t\tstr += \"; SameSite=Strict\";\n\t\t\tbreak;\n\t\tcase \"lax\":\n\t\t\tstr += \"; SameSite=Lax\";\n\t\t\tbreak;\n\t\tcase \"none\":\n\t\t\tstr += \"; SameSite=None\";\n\t\t\tbreak;\n\t\tdefault: throw new TypeError(`option sameSite is invalid: ${cookie.sameSite}`);\n\t}\n\treturn str;\n}\nfunction isDate(val) {\n\treturn __toString.call(val) === \"[object Date]\";\n}\nconst maxAgeRegExp = /^-?\\d+$/;\nconst _nullProto = /* @__PURE__ */ Object.getPrototypeOf({});\nfunction parseSetCookie(str, options) {\n\tconst len = str.length;\n\tlet _endIdx = len;\n\tlet eqIdx = -1;\n\tfor (let i = 0; i < len; i++) {\n\t\tconst c = str.charCodeAt(i);\n\t\tif (c === 59) {\n\t\t\t_endIdx = i;\n\t\t\tbreak;\n\t\t}\n\t\tif (c === 61 && eqIdx === -1) eqIdx = i;\n\t}\n\tif (eqIdx >= _endIdx) eqIdx = -1;\n\tconst name = eqIdx === -1 ? \"\" : _trim(str, 0, eqIdx);\n\tif (name && name in _nullProto) return void 0;\n\tlet value = eqIdx === -1 ? _trim(str, 0, _endIdx) : _trim(str, eqIdx + 1, _endIdx);\n\tif (!name && !value) return void 0;\n\tif (name.length + value.length > 4096) return void 0;\n\tif (options?.decode !== false) value = _decode(value, options?.decode);\n\tconst setCookie = {\n\t\tname,\n\t\tvalue\n\t};\n\tlet index = _endIdx + 1;\n\twhile (index < len) {\n\t\tlet endIdx = len;\n\t\tlet attrEqIdx = -1;\n\t\tfor (let i = index; i < len; i++) {\n\t\t\tconst c = str.charCodeAt(i);\n\t\t\tif (c === 59) {\n\t\t\t\tendIdx = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (c === 61 && attrEqIdx === -1) attrEqIdx = i;\n\t\t}\n\t\tif (attrEqIdx >= endIdx) attrEqIdx = -1;\n\t\tconst attr = attrEqIdx === -1 ? _trim(str, index, endIdx) : _trim(str, index, attrEqIdx);\n\t\tconst val = attrEqIdx === -1 ? void 0 : _trim(str, attrEqIdx + 1, endIdx);\n\t\tif (val === void 0 || val.length <= 1024) switch (attr.toLowerCase()) {\n\t\t\tcase \"httponly\":\n\t\t\t\tsetCookie.httpOnly = true;\n\t\t\t\tbreak;\n\t\t\tcase \"secure\":\n\t\t\t\tsetCookie.secure = true;\n\t\t\t\tbreak;\n\t\t\tcase \"partitioned\":\n\t\t\t\tsetCookie.partitioned = true;\n\t\t\t\tbreak;\n\t\t\tcase \"domain\":\n\t\t\t\tif (val) setCookie.domain = (val.charCodeAt(0) === 46 ? val.slice(1) : val).toLowerCase();\n\t\t\t\tbreak;\n\t\t\tcase \"path\":\n\t\t\t\tsetCookie.path = val;\n\t\t\t\tbreak;\n\t\t\tcase \"max-age\":\n\t\t\t\tif (val && maxAgeRegExp.test(val)) setCookie.maxAge = Math.min(Number(val), COOKIE_MAX_AGE_LIMIT);\n\t\t\t\tbreak;\n\t\t\tcase \"expires\": {\n\t\t\t\tif (!val) break;\n\t\t\t\tconst date = new Date(val);\n\t\t\t\tif (Number.isFinite(date.valueOf())) {\n\t\t\t\t\tconst maxDate = new Date(Date.now() + COOKIE_MAX_AGE_LIMIT * 1e3);\n\t\t\t\t\tsetCookie.expires = date > maxDate ? maxDate : date;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"priority\": {\n\t\t\t\tif (!val) break;\n\t\t\t\tconst priority = val.toLowerCase();\n\t\t\t\tif (priority === \"low\" || priority === \"medium\" || priority === \"high\") setCookie.priority = priority;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"samesite\": {\n\t\t\t\tif (!val) break;\n\t\t\t\tconst sameSite = val.toLowerCase();\n\t\t\t\tif (sameSite === \"lax\" || sameSite === \"strict\" || sameSite === \"none\") setCookie.sameSite = sameSite;\n\t\t\t\telse setCookie.sameSite = \"lax\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst attrLower = attr.toLowerCase();\n\t\t\t\tif (attrLower && !(attrLower in _nullProto)) setCookie[attrLower] = val;\n\t\t\t}\n\t\t}\n\t\tindex = endIdx + 1;\n\t}\n\treturn setCookie;\n}\nfunction _trim(str, start, end) {\n\tif (start === end) return \"\";\n\tlet s = start;\n\tlet e = end;\n\twhile (s < e && (str.charCodeAt(s) === 32 || str.charCodeAt(s) === 9)) s++;\n\twhile (e > s && (str.charCodeAt(e - 1) === 32 || str.charCodeAt(e - 1) === 9)) e--;\n\treturn str.slice(s, e);\n}\nfunction _decode(value, decode) {\n\tif (!decode && !value.includes(\"%\")) return value;\n\ttry {\n\t\treturn (decode || decodeURIComponent)(value);\n\t} catch {\n\t\treturn value;\n\t}\n}\nfunction splitSetCookieString(cookiesString) {\n\tif (Array.isArray(cookiesString)) return cookiesString.flatMap((c) => splitSetCookieString(c));\n\tif (typeof cookiesString !== \"string\") return [];\n\tconst cookiesStrings = [];\n\tlet pos = 0;\n\tlet start;\n\tlet ch;\n\tlet lastComma;\n\tlet nextStart;\n\tlet cookiesSeparatorFound;\n\tconst skipWhitespace = () => {\n\t\twhile (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) pos += 1;\n\t\treturn pos < cookiesString.length;\n\t};\n\tconst notSpecialChar = () => {\n\t\tch = cookiesString.charAt(pos);\n\t\treturn ch !== \"=\" && ch !== \";\" && ch !== \",\";\n\t};\n\twhile (pos < cookiesString.length) {\n\t\tstart = pos;\n\t\tcookiesSeparatorFound = false;\n\t\twhile (skipWhitespace()) {\n\t\t\tch = cookiesString.charAt(pos);\n\t\t\tif (ch === \",\") {\n\t\t\t\tlastComma = pos;\n\t\t\t\tpos += 1;\n\t\t\t\tskipWhitespace();\n\t\t\t\tnextStart = pos;\n\t\t\t\twhile (pos < cookiesString.length && notSpecialChar()) pos += 1;\n\t\t\t\tif (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n\t\t\t\t\tcookiesSeparatorFound = true;\n\t\t\t\t\tpos = nextStart;\n\t\t\t\t\tcookiesStrings.push(cookiesString.slice(start, lastComma));\n\t\t\t\t\tstart = pos;\n\t\t\t\t} else pos = lastComma + 1;\n\t\t\t} else pos += 1;\n\t\t}\n\t\tif (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.slice(start));\n\t}\n\treturn cookiesStrings;\n}\nexport { parse, parse as parseCookie, parseSetCookie, serialize, serialize as serializeCookie, splitSetCookieString, stringifyCookie };\n","import { splitSetCookieString } from \"cookie-es\";\n//#region src/ssr/headers.ts\nfunction toHeadersInstance(init) {\n\tif (init instanceof Headers) return init;\n\telse if (Array.isArray(init)) return new Headers(init);\n\telse if (typeof init === \"object\") return new Headers(init);\n\telse return null;\n}\nfunction mergeHeaders(...headers) {\n\treturn headers.reduce((acc, header) => {\n\t\tconst headersInstance = toHeadersInstance(header);\n\t\tif (!headersInstance) return acc;\n\t\tfor (const [key, value] of headersInstance.entries()) if (key === \"set-cookie\") splitSetCookieString(value).forEach((cookie) => acc.append(\"set-cookie\", cookie));\n\t\telse acc.set(key, value);\n\t\treturn acc;\n\t}, new Headers());\n}\n//#endregion\nexport { mergeHeaders };\n\n//# sourceMappingURL=headers.js.map","import type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n AnyStartInstanceOptions,\n CompiledFetcherFnOptions,\n CustomFetch,\n FunctionMiddlewareServerFnResult,\n Method,\n MiddlewareFn,\n NextFn,\n ServerFn,\n ServerFnBaseOptions,\n ServerFnBuilder,\n ServerFnMiddlewareOptions,\n ServerFnMiddlewareResult,\n createMiddleware as upstreamCreateMiddleware,\n createServerFn as upstreamCreateServerFn,\n createStart as upstreamCreateStart,\n} from '@tanstack/start-client-core';\nimport type { ClientFnMeta, ServerFnMeta } from '@tanstack/start-client-core';\nimport type { ClientOnlyFn, IsomorphicFn, IsomorphicFnBase, ServerOnlyFn } from '@tanstack/start-fn-stubs';\n\nimport { getEnv, getMiddlewareEntry, getServerFnEntry, registerMiddleware, registerServerFn, runInEnv } from '@tanstack-router-testing/router-testing-core';\nimport { isRedirect, useRouter } from '@tanstack/react-router';\nimport { parseRedirect } from '@tanstack/router-core';\nimport { mergeHeaders } from '@tanstack/router-core/ssr/client';\nimport { TSS_SERVER_FUNCTION, createNullProtoObject, execValidator, flattenMiddlewares, safeObjectMerge } from '@tanstack/start-client-core';\nimport { getStartContext } from '@tanstack/start-storage-context';\nimport * as React from 'react';\n\nexport * from '@tanstack/start-client-core';\n\ntype AnyFn = (...args: any[]) => any;\ntype MiddlewareType = 'request' | 'function';\ntype CreateServerFnShim = typeof upstreamCreateServerFn;\ntype CreateMiddlewareShim = typeof upstreamCreateMiddleware;\ninterface ServerExecutionResult {\n result?: unknown;\n error?: unknown;\n context?: unknown;\n}\ntype TestServerFnMiddlewareResult = ServerFnMiddlewareResult & {\n _callSiteFetch?: CustomFetch;\n};\ntype GlobalWithStartOptions = typeof globalThis & {\n __TSS_START_OPTIONS__?: AnyStartInstanceOptions | undefined;\n window?: Window & {\n __TSS_START_OPTIONS__?: AnyStartInstanceOptions | undefined;\n };\n};\n\nlet serverFnId = 0;\nconst TSS_SERVER_FUNCTION_FACTORY = Symbol.for('TSS_SERVER_FUNCTION_FACTORY');\n\nconst currentEnv = (): 'client' | 'server' => {\n const env = getEnv();\n if (env) return env;\n return globalThis.window === undefined ? 'server' : 'client';\n};\n\nconst setStartOptions = (options: AnyStartInstanceOptions): void => {\n const global = globalThis as GlobalWithStartOptions;\n global.__TSS_START_OPTIONS__ = options;\n if (global.window) {\n global.window.__TSS_START_OPTIONS__ = options;\n }\n};\n\nconst getStartOptions = (): AnyStartInstanceOptions | undefined => {\n const startContext = getStartContext({ throwIfNotFound: false });\n if (startContext?.startOptions) return startContext.startOptions as AnyStartInstanceOptions;\n\n const global = globalThis as GlobalWithStartOptions;\n return global.window?.__TSS_START_OPTIONS__ ?? global.__TSS_START_OPTIONS__;\n};\n\nexport const __setStartOptionsForTesting = (options: AnyStartInstanceOptions): void => {\n setStartOptions(options);\n};\n\nconst toPromise = async <T>(value: T | Promise<T>): Promise<T> => value;\n\nconst executeMiddleware = async (\n middlewares: (AnyFunctionMiddleware | AnyRequestMiddleware)[],\n env: 'client' | 'server',\n opts: ServerFnMiddlewareOptions,\n): Promise<ServerFnMiddlewareResult> => {\n const globalMiddlewares = (getStartOptions()?.functionMiddleware ?? []) as (AnyFunctionMiddleware | AnyRequestMiddleware)[];\n let flattenedMiddlewares = flattenMiddlewares([...globalMiddlewares, ...middlewares]);\n\n if (env === 'server') {\n const startContext = getStartContext({ throwIfNotFound: false });\n if (startContext?.executedRequestMiddlewares) {\n flattenedMiddlewares = flattenedMiddlewares.filter(middleware => !startContext.executedRequestMiddlewares.has(middleware));\n }\n }\n\n const callNextMiddleware: NextFn = async ctx => {\n const nextMiddleware = flattenedMiddlewares.shift();\n if (!nextMiddleware) return ctx;\n\n try {\n const middlewareOptions = nextMiddleware.options as { readonly type?: MiddlewareType; readonly server?: unknown };\n\n if (env === 'server' && middlewareOptions.type === 'request') {\n const requestMiddleware = middlewareOptions.server as AnyFn | undefined;\n if (!requestMiddleware) {\n return await callNextMiddleware(ctx);\n }\n\n const request = getRequestFromContext(ctx);\n const pathname = getPathnameFromRequest(request);\n const startContext = getStartContext({ throwIfNotFound: false });\n startContext?.executedRequestMiddlewares.add(nextMiddleware);\n\n const requestNext = async (userCtx: { readonly context?: unknown } | undefined = {}) => {\n const nextCtx = {\n ...ctx,\n request,\n pathname,\n context: safeObjectMerge(toOptionalRecord(ctx.context), toOptionalRecord(userCtx.context)),\n };\n const result = await callNextMiddleware(nextCtx as ServerFnMiddlewareResult);\n if (result.error) throw result.error;\n\n return {\n request,\n pathname,\n context: result.context,\n response: result.result instanceof Response ? result.result : new Response(null),\n };\n };\n\n const result = await requestMiddleware({\n request,\n pathname,\n context: ctx.context,\n serverFnMeta: ctx.serverFnMeta,\n next: requestNext,\n });\n\n if (result instanceof Response) {\n return { ...ctx, result };\n }\n\n return {\n ...ctx,\n request,\n pathname,\n context: safeObjectMerge(toOptionalRecord(ctx.context), toOptionalRecord((result as { readonly context?: unknown } | undefined)?.context)),\n result: (result as { readonly response?: Response } | undefined)?.response ?? ctx.result,\n };\n }\n\n if ('inputValidator' in nextMiddleware.options && nextMiddleware.options.inputValidator && env === 'server') {\n ctx.data = await execValidator(nextMiddleware.options.inputValidator, ctx.data);\n }\n\n let middlewareFn: MiddlewareFn | undefined;\n if (env === 'client' && 'client' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.client as unknown as MiddlewareFn | undefined;\n } else if (env === 'server' && 'server' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.server as unknown as MiddlewareFn | undefined;\n }\n\n if (!middlewareFn) {\n return await callNextMiddleware(ctx);\n }\n\n const userNext = async (userCtx: TestServerFnMiddlewareResult | undefined = {} as TestServerFnMiddlewareResult) => {\n const callCtx = ctx as TestServerFnMiddlewareResult;\n const nextCtx = {\n ...ctx,\n ...userCtx,\n context: safeObjectMerge(ctx.context, userCtx.context),\n sendContext: safeObjectMerge(ctx.sendContext, userCtx.sendContext),\n headers: mergeHeaders(ctx.headers, userCtx.headers),\n _callSiteFetch: callCtx._callSiteFetch,\n fetch: callCtx._callSiteFetch ?? userCtx.fetch ?? ctx.fetch,\n result: userCtx.result !== undefined ? userCtx.result : userCtx instanceof Response ? userCtx : ctx.result,\n error: userCtx.error ?? ctx.error,\n };\n\n const result = await callNextMiddleware(nextCtx as ServerFnMiddlewareResult);\n if (result.error) throw result.error;\n return result;\n };\n\n const result = await middlewareFn({\n ...ctx,\n next: userNext,\n });\n\n if (isRedirect(result)) {\n return { ...ctx, error: result };\n }\n\n if (result instanceof Response) {\n return { ...ctx, result };\n }\n\n if (!result) {\n throw new Error('User middleware returned undefined. You must call next() or return a result in your middlewares.');\n }\n\n return result;\n } catch (error) {\n return { ...ctx, error };\n }\n };\n\n return callNextMiddleware({\n ...opts,\n headers: opts.headers ?? {},\n sendContext: opts.sendContext ?? {},\n context: opts.context ?? createNullProtoObject(),\n _callSiteFetch: opts.fetch,\n } as ServerFnMiddlewareResult);\n};\n\nconst getRequestFromContext = (ctx: ServerFnMiddlewareOptions): Request => {\n const existing = (ctx as ServerFnMiddlewareOptions & { readonly request?: Request }).request;\n if (existing) return existing;\n\n const startContext = getStartContext({ throwIfNotFound: false });\n return startContext?.request ?? new Request('http://tanstack-router-testing.test/');\n};\n\nconst getPathnameFromRequest = (request: Request): string => new URL(request.url).pathname;\n\nconst toOptionalRecord = (value: unknown): Record<string, unknown> | undefined => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;\n return value as Record<string, unknown>;\n};\n\nconst createServerFnMiddleware = (options: ServerFnBaseOptions<any, any, any, any, any>, getFetcher: () => AnyFn): AnyFunctionMiddleware =>\n ({\n '~types': undefined,\n options: {\n inputValidator: options.inputValidator,\n client: async ({ next, sendContext, fetch, ...ctx }: ServerFnMiddlewareOptions & { next: NextFn }) => {\n const payload = {\n ...ctx,\n context: sendContext,\n fetch,\n };\n const res = await options.extractedFn?.(payload as CompiledFetcherFnOptions & ServerFnBaseOptions<any, Method>);\n return next(res as ServerFnMiddlewareResult);\n },\n server: async ({ next, ...ctx }: ServerFnMiddlewareOptions & { next: NextFn }) => {\n const fetcher = getFetcher();\n const entry = getServerFnEntry(fetcher);\n const impl = (entry?.mock ?? entry?.original ?? options.serverFn) as ServerFn<any, any, any, any, any> | undefined;\n const result = await impl?.(ctx as never);\n\n return next({\n ...ctx,\n result,\n } as ServerFnMiddlewareResult) as unknown as FunctionMiddlewareServerFnResult<any, any, any, any, any>;\n },\n },\n }) as unknown as AnyFunctionMiddleware;\n\nconst createServerMeta = (): ServerFnMeta => {\n serverFnId += 1;\n const id = `tanstack-router-testing:${serverFnId}`;\n return {\n id,\n name: id,\n filename: 'tanstack-router-testing://server-fn',\n };\n};\n\nconst normalizeDataOptions = (opts?: Partial<CompiledFetcherFnOptions>): Partial<CompiledFetcherFnOptions> => opts ?? {};\n\nexport const createServerFn: CreateServerFnShim = ((\n options: { method?: Method } | undefined,\n __opts: ServerFnBaseOptions<any, Method, any, any, any> | undefined,\n) => {\n const resolvedOptions = { ...(__opts ?? options) } as ServerFnBaseOptions<any, Method, any, any, any>;\n resolvedOptions.method ??= 'GET';\n\n const makeBuilder = (nextOptions: ServerFnBaseOptions<any, Method, any, any, any>): ServerFnBuilder<any, Method> => {\n const builder = ((newOptions?: { method?: Method }) =>\n createServerFn(undefined, {\n ...nextOptions,\n ...newOptions,\n })) as ServerFnBuilder<any, Method> & ((newOptions?: { method?: Method }) => ServerFnBuilder<any, Method>);\n\n Object.assign(builder, {\n '~types': undefined,\n [TSS_SERVER_FUNCTION_FACTORY]: true,\n options: nextOptions,\n middleware: (middlewares: readonly (AnyFunctionMiddleware | AnyRequestMiddleware | ServerFnBuilder<any, Method>)[]) => {\n const newMiddleware = [...((nextOptions.middleware as (AnyFunctionMiddleware | AnyRequestMiddleware)[]) || [])];\n for (const middleware of middlewares) {\n if (middleware && TSS_SERVER_FUNCTION_FACTORY in middleware && middleware.options.middleware) {\n newMiddleware.push(...(middleware.options.middleware as (AnyFunctionMiddleware | AnyRequestMiddleware)[]));\n } else {\n newMiddleware.push(middleware as AnyFunctionMiddleware | AnyRequestMiddleware);\n }\n }\n const res = createServerFn(undefined, {\n ...nextOptions,\n middleware: newMiddleware,\n }) as ServerFnBuilder<any, Method>;\n (res as unknown as Record<symbol, unknown>)[TSS_SERVER_FUNCTION_FACTORY] = true;\n return res;\n },\n inputValidator: (inputValidator: unknown) =>\n createServerFn(undefined, {\n ...nextOptions,\n inputValidator,\n }),\n handler: (...args: unknown[]) => {\n const extractedFromTransform = args.length > 1 ? (args[0] as AnyFn) : undefined;\n const serverFn = (args.length > 1 ? args[1] : args[0]) as ServerFn<any, Method, any, any, any>;\n const serverFnMeta = createServerMeta();\n const clientMeta: ClientFnMeta = { id: serverFnMeta.id };\n let fetcher: AnyFn;\n let resolvedMiddleware: (AnyFunctionMiddleware | AnyRequestMiddleware)[] = [];\n\n const executeServer = async (opts?: Partial<CompiledFetcherFnOptions> & { request?: Request }): Promise<ServerExecutionResult> => {\n const callOpts = normalizeDataOptions(opts) as Partial<CompiledFetcherFnOptions> & { request?: Request };\n const startContext = getStartContext({ throwIfNotFound: false });\n const request = callOpts.request ?? startContext?.request ?? new Request('http://tanstack-router-testing.test/_serverFn');\n const result: ServerFnMiddlewareResult = await runInEnv('server', () =>\n executeMiddleware(resolvedMiddleware, 'server', {\n ...callOpts,\n data: callOpts.data,\n method: nextOptions.method,\n serverFnMeta,\n signal: callOpts.signal ?? new AbortController().signal,\n context: safeObjectMerge(callOpts.context ?? createNullProtoObject(), startContext?.contextAfterGlobalMiddlewares),\n request,\n pathname: getPathnameFromRequest(request),\n } as ServerFnMiddlewareOptions),\n );\n\n return {\n result: result.result,\n error: result.error,\n context: result.sendContext,\n };\n };\n\n const extractedFn = Object.assign(\n async (opts?: CompiledFetcherFnOptions & ServerFnBaseOptions<any, Method>): Promise<unknown> => {\n if (extractedFromTransform) {\n return await extractedFromTransform(opts);\n }\n return await executeServer(opts);\n },\n {\n url: `/_serverFn/${serverFnMeta.id}`,\n serverFnMeta,\n },\n );\n\n const handlerOptions = {\n ...nextOptions,\n extractedFn,\n serverFn,\n };\n resolvedMiddleware = [\n ...((handlerOptions.middleware ?? []) as (AnyFunctionMiddleware | AnyRequestMiddleware)[]),\n createServerFnMiddleware(handlerOptions, () => fetcher),\n ];\n\n fetcher = Object.assign(\n async (opts?: Partial<CompiledFetcherFnOptions>): Promise<unknown> => {\n const callOpts = normalizeDataOptions(opts);\n if (currentEnv() === 'server') {\n const result = await executeServer(callOpts);\n const redirect = parseRedirect(result.error);\n if (redirect) throw redirect;\n if (result.error) throw result.error;\n return result.result;\n }\n\n const result = await runInEnv('client', () =>\n executeMiddleware(resolvedMiddleware, 'client', {\n ...extractedFn,\n ...handlerOptions,\n data: callOpts.data,\n headers: callOpts.headers,\n signal: callOpts.signal ?? new AbortController().signal,\n fetch: callOpts.fetch ?? getStartOptions()?.serverFns?.fetch,\n context: createNullProtoObject(),\n serverFnMeta: clientMeta,\n } as ServerFnMiddlewareOptions),\n );\n\n const redirect = parseRedirect(result.error);\n if (redirect) throw redirect;\n if (result.error) throw result.error;\n return result.result;\n },\n {\n ...extractedFn,\n [TSS_SERVER_FUNCTION]: true,\n method: nextOptions.method,\n __executeServer: executeServer,\n },\n );\n\n registerServerFn(fetcher, serverFn as unknown as AnyFn);\n return fetcher;\n },\n });\n\n return builder;\n };\n\n return makeBuilder(resolvedOptions);\n}) as CreateServerFnShim;\n\nconst createPhaseWrapper =\n (mw: object, phase: 'client' | 'server'): AnyFn =>\n async (ctx: unknown) => {\n const entry = getMiddlewareEntry(mw);\n const impl = phase === 'client' ? (entry?.mockClient ?? entry?.originalClient) : (entry?.mockServer ?? entry?.originalServer);\n if (!impl) return (ctx as { next?: AnyFn }).next?.();\n return impl(ctx as never);\n };\n\nexport const createMiddleware: CreateMiddlewareShim = ((options: { type?: MiddlewareType } | undefined, __opts: Record<string, unknown> | undefined) => {\n const makeBuilder = (resolvedOptions: Record<string, unknown>) => {\n const mw: Record<string, unknown> = {};\n const originalClient = resolvedOptions.client as AnyFn | undefined;\n const originalServer = resolvedOptions.server as AnyFn | undefined;\n const optionsWithWrappedPhases = {\n ...resolvedOptions,\n ...(originalClient ? { client: createPhaseWrapper(mw, 'client') } : {}),\n ...(originalServer ? { server: createPhaseWrapper(mw, 'server') } : {}),\n };\n\n Object.assign(mw, {\n '~types': undefined,\n options: optionsWithWrappedPhases,\n middleware: (middlewares: unknown) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n middleware: middlewares,\n } as never,\n ),\n inputValidator: (inputValidator: unknown) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n inputValidator,\n } as never,\n ),\n client: (client: AnyFn) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n client,\n } as never,\n ),\n server: (server: AnyFn) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n server,\n } as never,\n ),\n });\n\n registerMiddleware(mw, {\n ...(originalClient ? { client: originalClient } : {}),\n ...(originalServer ? { server: originalServer } : {}),\n });\n\n return mw;\n };\n\n return makeBuilder({\n type: 'request' satisfies MiddlewareType,\n ...(__opts ?? options),\n }) as never;\n}) as CreateMiddlewareShim;\n\nexport const createIsomorphicFn = (): IsomorphicFnBase => {\n const makeCallable = <TArgs extends any[], TServer, TClient>(\n serverImpl: ((...args: TArgs) => TServer) | undefined,\n clientImpl?: (...args: TArgs) => TClient,\n ): IsomorphicFn<TArgs, TServer, TClient> => {\n const fn = ((...args: TArgs) => {\n if (currentEnv() === 'server') return serverImpl?.(...args);\n return clientImpl?.(...args);\n }) as IsomorphicFn<TArgs, TServer, TClient>;\n return fn;\n };\n\n const base = (() => {}) as unknown as IsomorphicFnBase;\n return Object.assign(base, {\n server: <TArgs extends any[], TServer>(serverImpl: (...args: TArgs) => TServer): ServerOnlyFn<TArgs, TServer> => {\n const serverOnly = makeCallable<TArgs, TServer, undefined>(serverImpl) as ServerOnlyFn<TArgs, TServer>;\n return Object.assign(serverOnly, {\n client: <TClient>(clientImpl: (...args: TArgs) => TClient) => makeCallable(serverImpl, clientImpl),\n });\n },\n client: <TArgs extends any[], TClient>(clientImpl: (...args: TArgs) => TClient): ClientOnlyFn<TArgs, TClient> => {\n const clientOnly = makeCallable<TArgs, undefined, TClient>(undefined, clientImpl) as ClientOnlyFn<TArgs, TClient>;\n return Object.assign(clientOnly, {\n server: <TServer>(serverImpl: (...args: TArgs) => TServer) => makeCallable(serverImpl, clientImpl),\n });\n },\n });\n};\n\nexport const createServerOnlyFn = <TFn extends AnyFn>(fn: TFn): TFn =>\n ((...args: Parameters<TFn>) => {\n if (currentEnv() === 'client') {\n throw new Error('[tanstack-router-testing] createServerOnlyFn: attempted to call a server-only function in the client test environment.');\n }\n return fn(...args);\n }) as TFn;\n\nexport const createClientOnlyFn = <TFn extends AnyFn>(fn: TFn): TFn =>\n ((...args: Parameters<TFn>) => {\n if (currentEnv() === 'server') {\n throw new Error('[tanstack-router-testing] createClientOnlyFn: attempted to call a client-only function in the server test environment.');\n }\n return fn(...args);\n }) as TFn;\n\nexport const createStart = ((getOptions: () => Promise<Omit<AnyStartInstanceOptions, '~types'>> | Omit<AnyStartInstanceOptions, '~types'>) => {\n const getAndStoreOptions = async () => {\n const options = await toPromise(getOptions());\n setStartOptions(options as AnyStartInstanceOptions);\n return options;\n };\n\n const initialOptions = getOptions();\n if (initialOptions instanceof Promise) {\n void initialOptions.then(options => {\n setStartOptions(options as AnyStartInstanceOptions);\n });\n } else {\n setStartOptions(initialOptions as AnyStartInstanceOptions);\n }\n\n return {\n getOptions: getAndStoreOptions,\n createMiddleware,\n };\n}) as typeof upstreamCreateStart;\n\nexport function useServerFn<T extends (...deps: any[]) => Promise<any>>(serverFn: T): (...args: Parameters<T>) => ReturnType<T> {\n const router = useRouter();\n\n return React.useCallback(\n async (...args: any[]) => {\n try {\n const res = await serverFn(...args);\n\n if (isRedirect(res)) {\n throw res;\n }\n\n return res;\n } catch (error) {\n if (isRedirect(error)) {\n error.options._fromLocation = router.stores.location.get();\n return router.navigate(router.resolveRedirect(error).options);\n }\n\n throw error;\n }\n },\n [router, serverFn],\n ) as any;\n}\n"],"x_google_ignoreList":[0,1,2],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shim-C-PA0sYH.mjs","names":["createServerFn","createMiddleware","createStart"],"sources":["../../../node_modules/.pnpm/@tanstack+router-core@1.168.16/node_modules/@tanstack/router-core/dist/esm/redirect.js","../../../node_modules/.pnpm/cookie-es@3.1.1/node_modules/cookie-es/dist/index.mjs","../../../node_modules/.pnpm/@tanstack+router-core@1.168.16/node_modules/@tanstack/router-core/dist/esm/ssr/headers.js","../src/shim.ts"],"sourcesContent":["//#region src/redirect.ts\n/**\n* Create a redirect Response understood by TanStack Router.\n*\n* Use from route `loader`/`beforeLoad` or server functions to trigger a\n* navigation. If `throw: true` is set, the redirect is thrown instead of\n* returned. When an absolute `href` is supplied and `reloadDocument` is not\n* set, a full-document navigation is inferred.\n*\n* @param opts Options for the redirect. Common fields:\n* - `href`: absolute URL for external redirects; infers `reloadDocument`.\n* - `statusCode`: HTTP status code to use (defaults to 307).\n* - `headers`: additional headers to include on the Response.\n* - Standard navigation options like `to`, `params`, `search`, `replace`,\n* and `reloadDocument` for internal redirects.\n* @returns A Response augmented with router navigation options.\n* @link https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction\n*/\nfunction redirect(opts) {\n\topts.statusCode = opts.statusCode || opts.code || 307;\n\tif (!opts._builtLocation && !opts.reloadDocument && typeof opts.href === \"string\") try {\n\t\tnew URL(opts.href);\n\t\topts.reloadDocument = true;\n\t} catch {}\n\tconst headers = new Headers(opts.headers);\n\tif (opts.href && headers.get(\"Location\") === null) headers.set(\"Location\", opts.href);\n\tconst response = new Response(null, {\n\t\tstatus: opts.statusCode,\n\t\theaders\n\t});\n\tresponse.options = opts;\n\tif (opts.throw) throw response;\n\treturn response;\n}\n/** Check whether a value is a TanStack Router redirect Response. */\n/** Check whether a value is a TanStack Router redirect Response. */\nfunction isRedirect(obj) {\n\treturn obj instanceof Response && !!obj.options;\n}\n/** True if value is a redirect with a resolved `href` location. */\n/** True if value is a redirect with a resolved `href` location. */\nfunction isResolvedRedirect(obj) {\n\treturn isRedirect(obj) && !!obj.options.href;\n}\n/** Parse a serialized redirect object back into a redirect Response. */\n/** Parse a serialized redirect object back into a redirect Response. */\nfunction parseRedirect(obj) {\n\tif (obj !== null && typeof obj === \"object\" && obj.isSerializedRedirect) return redirect(obj);\n}\n//#endregion\nexport { isRedirect, isResolvedRedirect, parseRedirect, redirect };\n\n//# sourceMappingURL=redirect.js.map","const COOKIE_MAX_AGE_LIMIT = 3456e4;\nfunction endIndex(str, min, len) {\n\tconst index = str.indexOf(\";\", min);\n\treturn index === -1 ? len : index;\n}\nfunction eqIndex(str, min, max) {\n\tconst index = str.indexOf(\"=\", min);\n\treturn index < max ? index : -1;\n}\nfunction valueSlice(str, min, max) {\n\tif (min === max) return \"\";\n\tlet start = min;\n\tlet end = max;\n\tdo {\n\t\tconst code = str.charCodeAt(start);\n\t\tif (code !== 32 && code !== 9) break;\n\t} while (++start < end);\n\twhile (end > start) {\n\t\tconst code = str.charCodeAt(end - 1);\n\t\tif (code !== 32 && code !== 9) break;\n\t\tend--;\n\t}\n\treturn str.slice(start, end);\n}\nconst NullObject = /* @__PURE__ */ (() => {\n\tconst C = function() {};\n\tC.prototype = Object.create(null);\n\treturn C;\n})();\nfunction parse(str, options) {\n\tconst obj = new NullObject();\n\tconst len = str.length;\n\tif (len < 2) return obj;\n\tconst dec = options?.decode || decode;\n\tconst allowMultiple = options?.allowMultiple || false;\n\tlet index = 0;\n\tdo {\n\t\tconst eqIdx = eqIndex(str, index, len);\n\t\tif (eqIdx === -1) break;\n\t\tconst endIdx = endIndex(str, index, len);\n\t\tif (eqIdx > endIdx) {\n\t\t\tindex = str.lastIndexOf(\";\", eqIdx - 1) + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = valueSlice(str, index, eqIdx);\n\t\tif (options?.filter && !options.filter(key)) {\n\t\t\tindex = endIdx + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst val = dec(valueSlice(str, eqIdx + 1, endIdx));\n\t\tif (allowMultiple) {\n\t\t\tconst existing = obj[key];\n\t\t\tif (existing === void 0) obj[key] = val;\n\t\t\telse if (Array.isArray(existing)) existing.push(val);\n\t\t\telse obj[key] = [existing, val];\n\t\t} else if (obj[key] === void 0) obj[key] = val;\n\t\tindex = endIdx + 1;\n\t} while (index < len);\n\treturn obj;\n}\nfunction decode(str) {\n\tif (!str.includes(\"%\")) return str;\n\ttry {\n\t\treturn decodeURIComponent(str);\n\t} catch {\n\t\treturn str;\n\t}\n}\nconst cookieNameRegExp = /^[\\u0021-\\u003A\\u003C\\u003E-\\u007E]+$/;\nconst cookieValueRegExp = /^[\\u0021-\\u003A\\u003C-\\u007E]*$/;\nconst domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;\nconst pathValueRegExp = /^[\\u0020-\\u003A\\u003C-\\u007E]*$/;\nconst __toString = Object.prototype.toString;\nfunction stringifyCookie(cookie, options) {\n\tconst enc = options?.encode || encodeURIComponent;\n\tconst keys = Object.keys(cookie);\n\tlet str = \"\";\n\tfor (const [i, name] of keys.entries()) {\n\t\tconst val = cookie[name];\n\t\tif (val === void 0) continue;\n\t\tif (!cookieNameRegExp.test(name)) throw new TypeError(`cookie name is invalid: ${name}`);\n\t\tconst value = enc(val);\n\t\tif (!cookieValueRegExp.test(value)) throw new TypeError(`cookie val is invalid: ${val}`);\n\t\tif (i > 0) str += \"; \";\n\t\tstr += name + \"=\" + value;\n\t}\n\treturn str;\n}\nfunction serialize(_a0, _a1, _a2) {\n\tconst isObj = typeof _a0 === \"object\" && _a0 !== null;\n\tconst options = isObj ? _a1 : _a2;\n\tconst stringify = options?.stringify || JSON.stringify;\n\tconst cookie = isObj ? _a0 : {\n\t\t..._a2,\n\t\tname: _a0,\n\t\tvalue: _a1 == void 0 ? \"\" : typeof _a1 === \"string\" ? _a1 : stringify(_a1)\n\t};\n\tconst enc = options?.encode || encodeURIComponent;\n\tif (!cookieNameRegExp.test(cookie.name)) throw new TypeError(`argument name is invalid: ${cookie.name}`);\n\tconst value = cookie.value ? enc(cookie.value) : \"\";\n\tif (!cookieValueRegExp.test(value)) throw new TypeError(`argument val is invalid: ${cookie.value}`);\n\tif (!cookie.secure) {\n\t\tif (cookie.partitioned) throw new TypeError(`Partitioned cookies must have the Secure attribute`);\n\t\tif (cookie.sameSite && String(cookie.sameSite).toLowerCase() === \"none\") throw new TypeError(`SameSite=None cookies must have the Secure attribute`);\n\t\tif (cookie.name.length > 9 && cookie.name.charCodeAt(0) === 95 && cookie.name.charCodeAt(1) === 95) {\n\t\t\tconst nameLower = cookie.name.toLowerCase();\n\t\t\tif (nameLower.startsWith(\"__secure-\") || nameLower.startsWith(\"__host-\")) throw new TypeError(`${cookie.name} cookies must have the Secure attribute`);\n\t\t}\n\t}\n\tif (cookie.name.length > 7 && cookie.name.charCodeAt(0) === 95 && cookie.name.charCodeAt(1) === 95 && cookie.name.toLowerCase().startsWith(\"__host-\")) {\n\t\tif (cookie.path !== \"/\") throw new TypeError(`__Host- cookies must have Path=/`);\n\t\tif (cookie.domain) throw new TypeError(`__Host- cookies must not have a Domain attribute`);\n\t}\n\tlet str = cookie.name + \"=\" + value;\n\tif (cookie.maxAge !== void 0) {\n\t\tif (!Number.isInteger(cookie.maxAge)) throw new TypeError(`option maxAge is invalid: ${cookie.maxAge}`);\n\t\tstr += \"; Max-Age=\" + Math.max(0, Math.min(cookie.maxAge, COOKIE_MAX_AGE_LIMIT));\n\t}\n\tif (cookie.domain) {\n\t\tif (!domainValueRegExp.test(cookie.domain)) throw new TypeError(`option domain is invalid: ${cookie.domain}`);\n\t\tstr += \"; Domain=\" + cookie.domain;\n\t}\n\tif (cookie.path) {\n\t\tif (!pathValueRegExp.test(cookie.path)) throw new TypeError(`option path is invalid: ${cookie.path}`);\n\t\tstr += \"; Path=\" + cookie.path;\n\t}\n\tif (cookie.expires) {\n\t\tif (!isDate(cookie.expires) || !Number.isFinite(cookie.expires.valueOf())) throw new TypeError(`option expires is invalid: ${cookie.expires}`);\n\t\tstr += \"; Expires=\" + cookie.expires.toUTCString();\n\t}\n\tif (cookie.httpOnly) str += \"; HttpOnly\";\n\tif (cookie.secure) str += \"; Secure\";\n\tif (cookie.partitioned) str += \"; Partitioned\";\n\tif (cookie.priority) switch (typeof cookie.priority === \"string\" ? cookie.priority.toLowerCase() : void 0) {\n\t\tcase \"low\":\n\t\t\tstr += \"; Priority=Low\";\n\t\t\tbreak;\n\t\tcase \"medium\":\n\t\t\tstr += \"; Priority=Medium\";\n\t\t\tbreak;\n\t\tcase \"high\":\n\t\t\tstr += \"; Priority=High\";\n\t\t\tbreak;\n\t\tdefault: throw new TypeError(`option priority is invalid: ${cookie.priority}`);\n\t}\n\tif (cookie.sameSite) switch (typeof cookie.sameSite === \"string\" ? cookie.sameSite.toLowerCase() : cookie.sameSite) {\n\t\tcase true:\n\t\tcase \"strict\":\n\t\t\tstr += \"; SameSite=Strict\";\n\t\t\tbreak;\n\t\tcase \"lax\":\n\t\t\tstr += \"; SameSite=Lax\";\n\t\t\tbreak;\n\t\tcase \"none\":\n\t\t\tstr += \"; SameSite=None\";\n\t\t\tbreak;\n\t\tdefault: throw new TypeError(`option sameSite is invalid: ${cookie.sameSite}`);\n\t}\n\treturn str;\n}\nfunction isDate(val) {\n\treturn __toString.call(val) === \"[object Date]\";\n}\nconst maxAgeRegExp = /^-?\\d+$/;\nconst _nullProto = /* @__PURE__ */ Object.getPrototypeOf({});\nfunction parseSetCookie(str, options) {\n\tconst len = str.length;\n\tlet _endIdx = len;\n\tlet eqIdx = -1;\n\tfor (let i = 0; i < len; i++) {\n\t\tconst c = str.charCodeAt(i);\n\t\tif (c === 59) {\n\t\t\t_endIdx = i;\n\t\t\tbreak;\n\t\t}\n\t\tif (c === 61 && eqIdx === -1) eqIdx = i;\n\t}\n\tif (eqIdx >= _endIdx) eqIdx = -1;\n\tconst name = eqIdx === -1 ? \"\" : _trim(str, 0, eqIdx);\n\tif (name && name in _nullProto) return void 0;\n\tlet value = eqIdx === -1 ? _trim(str, 0, _endIdx) : _trim(str, eqIdx + 1, _endIdx);\n\tif (!name && !value) return void 0;\n\tif (name.length + value.length > 4096) return void 0;\n\tif (options?.decode !== false) value = _decode(value, options?.decode);\n\tconst setCookie = {\n\t\tname,\n\t\tvalue\n\t};\n\tlet index = _endIdx + 1;\n\twhile (index < len) {\n\t\tlet endIdx = len;\n\t\tlet attrEqIdx = -1;\n\t\tfor (let i = index; i < len; i++) {\n\t\t\tconst c = str.charCodeAt(i);\n\t\t\tif (c === 59) {\n\t\t\t\tendIdx = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (c === 61 && attrEqIdx === -1) attrEqIdx = i;\n\t\t}\n\t\tif (attrEqIdx >= endIdx) attrEqIdx = -1;\n\t\tconst attr = attrEqIdx === -1 ? _trim(str, index, endIdx) : _trim(str, index, attrEqIdx);\n\t\tconst val = attrEqIdx === -1 ? void 0 : _trim(str, attrEqIdx + 1, endIdx);\n\t\tif (val === void 0 || val.length <= 1024) switch (attr.toLowerCase()) {\n\t\t\tcase \"httponly\":\n\t\t\t\tsetCookie.httpOnly = true;\n\t\t\t\tbreak;\n\t\t\tcase \"secure\":\n\t\t\t\tsetCookie.secure = true;\n\t\t\t\tbreak;\n\t\t\tcase \"partitioned\":\n\t\t\t\tsetCookie.partitioned = true;\n\t\t\t\tbreak;\n\t\t\tcase \"domain\":\n\t\t\t\tif (val) setCookie.domain = (val.charCodeAt(0) === 46 ? val.slice(1) : val).toLowerCase();\n\t\t\t\tbreak;\n\t\t\tcase \"path\":\n\t\t\t\tsetCookie.path = val;\n\t\t\t\tbreak;\n\t\t\tcase \"max-age\":\n\t\t\t\tif (val && maxAgeRegExp.test(val)) setCookie.maxAge = Math.min(Number(val), COOKIE_MAX_AGE_LIMIT);\n\t\t\t\tbreak;\n\t\t\tcase \"expires\": {\n\t\t\t\tif (!val) break;\n\t\t\t\tconst date = new Date(val);\n\t\t\t\tif (Number.isFinite(date.valueOf())) {\n\t\t\t\t\tconst maxDate = new Date(Date.now() + COOKIE_MAX_AGE_LIMIT * 1e3);\n\t\t\t\t\tsetCookie.expires = date > maxDate ? maxDate : date;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"priority\": {\n\t\t\t\tif (!val) break;\n\t\t\t\tconst priority = val.toLowerCase();\n\t\t\t\tif (priority === \"low\" || priority === \"medium\" || priority === \"high\") setCookie.priority = priority;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"samesite\": {\n\t\t\t\tif (!val) break;\n\t\t\t\tconst sameSite = val.toLowerCase();\n\t\t\t\tif (sameSite === \"lax\" || sameSite === \"strict\" || sameSite === \"none\") setCookie.sameSite = sameSite;\n\t\t\t\telse setCookie.sameSite = \"lax\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst attrLower = attr.toLowerCase();\n\t\t\t\tif (attrLower && !(attrLower in _nullProto)) setCookie[attrLower] = val;\n\t\t\t}\n\t\t}\n\t\tindex = endIdx + 1;\n\t}\n\treturn setCookie;\n}\nfunction _trim(str, start, end) {\n\tif (start === end) return \"\";\n\tlet s = start;\n\tlet e = end;\n\twhile (s < e && (str.charCodeAt(s) === 32 || str.charCodeAt(s) === 9)) s++;\n\twhile (e > s && (str.charCodeAt(e - 1) === 32 || str.charCodeAt(e - 1) === 9)) e--;\n\treturn str.slice(s, e);\n}\nfunction _decode(value, decode) {\n\tif (!decode && !value.includes(\"%\")) return value;\n\ttry {\n\t\treturn (decode || decodeURIComponent)(value);\n\t} catch {\n\t\treturn value;\n\t}\n}\nfunction splitSetCookieString(cookiesString) {\n\tif (Array.isArray(cookiesString)) return cookiesString.flatMap((c) => splitSetCookieString(c));\n\tif (typeof cookiesString !== \"string\") return [];\n\tconst cookiesStrings = [];\n\tlet pos = 0;\n\tlet start;\n\tlet ch;\n\tlet lastComma;\n\tlet nextStart;\n\tlet cookiesSeparatorFound;\n\tconst skipWhitespace = () => {\n\t\twhile (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) pos += 1;\n\t\treturn pos < cookiesString.length;\n\t};\n\tconst notSpecialChar = () => {\n\t\tch = cookiesString.charAt(pos);\n\t\treturn ch !== \"=\" && ch !== \";\" && ch !== \",\";\n\t};\n\twhile (pos < cookiesString.length) {\n\t\tstart = pos;\n\t\tcookiesSeparatorFound = false;\n\t\twhile (skipWhitespace()) {\n\t\t\tch = cookiesString.charAt(pos);\n\t\t\tif (ch === \",\") {\n\t\t\t\tlastComma = pos;\n\t\t\t\tpos += 1;\n\t\t\t\tskipWhitespace();\n\t\t\t\tnextStart = pos;\n\t\t\t\twhile (pos < cookiesString.length && notSpecialChar()) pos += 1;\n\t\t\t\tif (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n\t\t\t\t\tcookiesSeparatorFound = true;\n\t\t\t\t\tpos = nextStart;\n\t\t\t\t\tcookiesStrings.push(cookiesString.slice(start, lastComma));\n\t\t\t\t\tstart = pos;\n\t\t\t\t} else pos = lastComma + 1;\n\t\t\t} else pos += 1;\n\t\t}\n\t\tif (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.slice(start));\n\t}\n\treturn cookiesStrings;\n}\nexport { parse, parse as parseCookie, parseSetCookie, serialize, serialize as serializeCookie, splitSetCookieString, stringifyCookie };\n","import { splitSetCookieString } from \"cookie-es\";\n//#region src/ssr/headers.ts\nfunction toHeadersInstance(init) {\n\tif (init instanceof Headers) return init;\n\telse if (Array.isArray(init)) return new Headers(init);\n\telse if (typeof init === \"object\") return new Headers(init);\n\telse return null;\n}\nfunction mergeHeaders(...headers) {\n\treturn headers.reduce((acc, header) => {\n\t\tconst headersInstance = toHeadersInstance(header);\n\t\tif (!headersInstance) return acc;\n\t\tfor (const [key, value] of headersInstance.entries()) if (key === \"set-cookie\") splitSetCookieString(value).forEach((cookie) => acc.append(\"set-cookie\", cookie));\n\t\telse acc.set(key, value);\n\t\treturn acc;\n\t}, new Headers());\n}\n//#endregion\nexport { mergeHeaders };\n\n//# sourceMappingURL=headers.js.map","import type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n AnyStartInstanceOptions,\n CompiledFetcherFnOptions,\n CustomFetch,\n FunctionMiddlewareServerFnResult,\n Method,\n MiddlewareFn,\n NextFn,\n ServerFn,\n ServerFnBaseOptions,\n ServerFnBuilder,\n ServerFnMiddlewareOptions,\n ServerFnMiddlewareResult,\n createMiddleware as upstreamCreateMiddleware,\n createServerFn as upstreamCreateServerFn,\n createStart as upstreamCreateStart,\n} from '@tanstack/start-client-core';\nimport type { ClientFnMeta, ServerFnMeta } from '@tanstack/start-client-core';\nimport type { ClientOnlyFn, IsomorphicFn, IsomorphicFnBase, ServerOnlyFn } from '@tanstack/start-fn-stubs';\n\nimport { getEnv, getMiddlewareEntry, getServerFnEntry, registerMiddleware, registerServerFn, runInEnv } from '@tanstack-router-testing/router-testing-core';\nimport { isRedirect, useRouter } from '@tanstack/react-router';\nimport { parseRedirect } from '@tanstack/router-core';\nimport { mergeHeaders } from '@tanstack/router-core/ssr/client';\nimport { TSS_SERVER_FUNCTION, createNullProtoObject, execValidator, flattenMiddlewares, safeObjectMerge } from '@tanstack/start-client-core';\nimport { getStartContext } from '@tanstack/start-storage-context';\nimport * as React from 'react';\n\nexport * from '@tanstack/start-client-core';\n\ntype AnyFn = (...args: any[]) => any;\ntype MiddlewareType = 'request' | 'function';\ntype CreateServerFnShim = typeof upstreamCreateServerFn;\ntype CreateMiddlewareShim = typeof upstreamCreateMiddleware;\ninterface ServerExecutionResult {\n result?: unknown;\n error?: unknown;\n context?: unknown;\n}\ntype TestServerFnMiddlewareResult = ServerFnMiddlewareResult & {\n _callSiteFetch?: CustomFetch;\n};\ntype GlobalWithStartOptions = typeof globalThis & {\n __TSS_START_OPTIONS__?: AnyStartInstanceOptions | undefined;\n window?: Window & {\n __TSS_START_OPTIONS__?: AnyStartInstanceOptions | undefined;\n };\n};\n\nlet serverFnId = 0;\nconst TSS_SERVER_FUNCTION_FACTORY = Symbol.for('TSS_SERVER_FUNCTION_FACTORY');\n\nconst currentEnv = (): 'client' | 'server' => {\n const env = getEnv();\n if (env) return env;\n return globalThis.window === undefined ? 'server' : 'client';\n};\n\nconst setStartOptions = (options: AnyStartInstanceOptions): void => {\n const global = globalThis as GlobalWithStartOptions;\n global.__TSS_START_OPTIONS__ = options;\n if (global.window) {\n global.window.__TSS_START_OPTIONS__ = options;\n }\n};\n\nconst getStartOptions = (): AnyStartInstanceOptions | undefined => {\n const startContext = getStartContext({ throwIfNotFound: false });\n if (startContext?.startOptions) return startContext.startOptions as AnyStartInstanceOptions;\n\n const global = globalThis as GlobalWithStartOptions;\n return global.window?.__TSS_START_OPTIONS__ ?? global.__TSS_START_OPTIONS__;\n};\n\nexport const __setStartOptionsForTesting = (options: AnyStartInstanceOptions): void => {\n setStartOptions(options);\n};\n\nconst toPromise = async <T>(value: T | Promise<T>): Promise<T> => value;\n\nconst executeMiddleware = async (\n middlewares: (AnyFunctionMiddleware | AnyRequestMiddleware)[],\n env: 'client' | 'server',\n opts: ServerFnMiddlewareOptions,\n): Promise<ServerFnMiddlewareResult> => {\n const globalMiddlewares = (getStartOptions()?.functionMiddleware ?? []) as (AnyFunctionMiddleware | AnyRequestMiddleware)[];\n let flattenedMiddlewares = flattenMiddlewares([...globalMiddlewares, ...middlewares]);\n\n if (env === 'server') {\n const startContext = getStartContext({ throwIfNotFound: false });\n if (startContext?.executedRequestMiddlewares) {\n flattenedMiddlewares = flattenedMiddlewares.filter(middleware => !startContext.executedRequestMiddlewares.has(middleware));\n }\n }\n\n const callNextMiddleware: NextFn = async ctx => {\n const nextMiddleware = flattenedMiddlewares.shift();\n if (!nextMiddleware) return ctx;\n\n try {\n const middlewareOptions = nextMiddleware.options as { readonly type?: MiddlewareType; readonly server?: unknown };\n\n if (env === 'server' && middlewareOptions.type === 'request') {\n const requestMiddleware = middlewareOptions.server as AnyFn | undefined;\n if (!requestMiddleware) {\n return await callNextMiddleware(ctx);\n }\n\n const request = getRequestFromContext(ctx);\n const pathname = getPathnameFromRequest(request);\n const startContext = getStartContext({ throwIfNotFound: false });\n startContext?.executedRequestMiddlewares.add(nextMiddleware);\n\n const requestNext = async (userCtx: { readonly context?: unknown } | undefined = {}) => {\n const nextCtx = {\n ...ctx,\n request,\n pathname,\n context: safeObjectMerge(toOptionalRecord(ctx.context), toOptionalRecord(userCtx.context)),\n };\n const result = await callNextMiddleware(nextCtx as ServerFnMiddlewareResult);\n if (result.error) throw result.error;\n\n return {\n request,\n pathname,\n context: result.context,\n response: result.result instanceof Response ? result.result : new Response(null),\n };\n };\n\n const result = await requestMiddleware({\n request,\n pathname,\n context: ctx.context,\n serverFnMeta: ctx.serverFnMeta,\n next: requestNext,\n });\n\n if (result instanceof Response) {\n return { ...ctx, result };\n }\n\n return {\n ...ctx,\n request,\n pathname,\n context: safeObjectMerge(toOptionalRecord(ctx.context), toOptionalRecord((result as { readonly context?: unknown } | undefined)?.context)),\n result: (result as { readonly response?: Response } | undefined)?.response ?? ctx.result,\n };\n }\n\n if ('inputValidator' in nextMiddleware.options && nextMiddleware.options.inputValidator && env === 'server') {\n ctx.data = await execValidator(nextMiddleware.options.inputValidator, ctx.data);\n }\n\n let middlewareFn: MiddlewareFn | undefined;\n if (env === 'client' && 'client' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.client as unknown as MiddlewareFn | undefined;\n } else if (env === 'server' && 'server' in nextMiddleware.options) {\n middlewareFn = nextMiddleware.options.server as unknown as MiddlewareFn | undefined;\n }\n\n if (!middlewareFn) {\n return await callNextMiddleware(ctx);\n }\n\n const userNext = async (userCtx: TestServerFnMiddlewareResult | undefined = {} as TestServerFnMiddlewareResult) => {\n const callCtx = ctx as TestServerFnMiddlewareResult;\n const nextCtx = {\n ...ctx,\n ...userCtx,\n context: safeObjectMerge(ctx.context, userCtx.context),\n sendContext: safeObjectMerge(ctx.sendContext, userCtx.sendContext),\n headers: mergeHeaders(ctx.headers, userCtx.headers),\n _callSiteFetch: callCtx._callSiteFetch,\n fetch: callCtx._callSiteFetch ?? userCtx.fetch ?? ctx.fetch,\n result: userCtx.result !== undefined ? userCtx.result : userCtx instanceof Response ? userCtx : ctx.result,\n error: userCtx.error ?? ctx.error,\n };\n\n const result = await callNextMiddleware(nextCtx as ServerFnMiddlewareResult);\n if (result.error) throw result.error;\n return result;\n };\n\n const result = await middlewareFn({\n ...ctx,\n next: userNext,\n });\n\n if (isRedirect(result)) {\n return { ...ctx, error: result };\n }\n\n if (result instanceof Response) {\n return { ...ctx, result };\n }\n\n if (!result) {\n throw new Error('User middleware returned undefined. You must call next() or return a result in your middlewares.');\n }\n\n return result;\n } catch (error) {\n return { ...ctx, error };\n }\n };\n\n return callNextMiddleware({\n ...opts,\n headers: opts.headers ?? {},\n sendContext: opts.sendContext ?? {},\n context: opts.context ?? createNullProtoObject(),\n _callSiteFetch: opts.fetch,\n } as ServerFnMiddlewareResult);\n};\n\nconst getRequestFromContext = (ctx: ServerFnMiddlewareOptions): Request => {\n const existing = (ctx as ServerFnMiddlewareOptions & { readonly request?: Request }).request;\n if (existing) return existing;\n\n const startContext = getStartContext({ throwIfNotFound: false });\n return startContext?.request ?? new Request('http://tanstack-router-testing.test/');\n};\n\nconst getPathnameFromRequest = (request: Request): string => new URL(request.url).pathname;\n\nconst toOptionalRecord = (value: unknown): Record<string, unknown> | undefined => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;\n return value as Record<string, unknown>;\n};\n\nconst createServerFnMiddleware = (options: ServerFnBaseOptions<any, any, any, any, any>, getFetcher: () => AnyFn): AnyFunctionMiddleware =>\n ({\n '~types': undefined,\n options: {\n inputValidator: options.inputValidator,\n client: async ({ next, sendContext, fetch, ...ctx }: ServerFnMiddlewareOptions & { next: NextFn }) => {\n const payload = {\n ...ctx,\n context: sendContext,\n fetch,\n };\n const res = await options.extractedFn?.(payload as CompiledFetcherFnOptions & ServerFnBaseOptions<any, Method>);\n return next(res as ServerFnMiddlewareResult);\n },\n server: async ({ next, ...ctx }: ServerFnMiddlewareOptions & { next: NextFn }) => {\n const fetcher = getFetcher();\n const entry = getServerFnEntry(fetcher);\n const impl = (entry?.mock ?? entry?.original ?? options.serverFn) as ServerFn<any, any, any, any, any> | undefined;\n const result = await impl?.(ctx as never);\n\n return next({\n ...ctx,\n result,\n } as ServerFnMiddlewareResult) as unknown as FunctionMiddlewareServerFnResult<any, any, any, any, any>;\n },\n },\n }) as unknown as AnyFunctionMiddleware;\n\nconst createServerMeta = (): ServerFnMeta => {\n serverFnId += 1;\n const id = `tanstack-router-testing:${serverFnId}`;\n return {\n id,\n name: id,\n filename: 'tanstack-router-testing://server-fn',\n };\n};\n\nconst normalizeDataOptions = (opts?: Partial<CompiledFetcherFnOptions>): Partial<CompiledFetcherFnOptions> => opts ?? {};\n\nexport const createServerFn: CreateServerFnShim = ((\n options: { method?: Method } | undefined,\n __opts: ServerFnBaseOptions<any, Method, any, any, any> | undefined,\n) => {\n const resolvedOptions = { ...(__opts ?? options) } as ServerFnBaseOptions<any, Method, any, any, any>;\n resolvedOptions.method ??= 'GET';\n\n const makeBuilder = (nextOptions: ServerFnBaseOptions<any, Method, any, any, any>): ServerFnBuilder<any, Method> => {\n const builder = ((newOptions?: { method?: Method }) =>\n createServerFn(undefined, {\n ...nextOptions,\n ...newOptions,\n })) as ServerFnBuilder<any, Method> & ((newOptions?: { method?: Method }) => ServerFnBuilder<any, Method>);\n\n Object.assign(builder, {\n '~types': undefined,\n [TSS_SERVER_FUNCTION_FACTORY]: true,\n options: nextOptions,\n middleware: (middlewares: readonly (AnyFunctionMiddleware | AnyRequestMiddleware | ServerFnBuilder<any, Method>)[]) => {\n const newMiddleware = [...((nextOptions.middleware as (AnyFunctionMiddleware | AnyRequestMiddleware)[]) || [])];\n for (const middleware of middlewares) {\n if (middleware && TSS_SERVER_FUNCTION_FACTORY in middleware && middleware.options.middleware) {\n newMiddleware.push(...(middleware.options.middleware as (AnyFunctionMiddleware | AnyRequestMiddleware)[]));\n } else {\n newMiddleware.push(middleware as AnyFunctionMiddleware | AnyRequestMiddleware);\n }\n }\n const res = createServerFn(undefined, {\n ...nextOptions,\n middleware: newMiddleware,\n }) as ServerFnBuilder<any, Method>;\n (res as unknown as Record<symbol, unknown>)[TSS_SERVER_FUNCTION_FACTORY] = true;\n return res;\n },\n inputValidator: (inputValidator: unknown) =>\n createServerFn(undefined, {\n ...nextOptions,\n inputValidator,\n }),\n handler: (...args: unknown[]) => {\n const extractedFromTransform = args.length > 1 ? (args[0] as AnyFn) : undefined;\n const serverFn = (args.length > 1 ? args[1] : args[0]) as ServerFn<any, Method, any, any, any>;\n const serverFnMeta = createServerMeta();\n const clientMeta: ClientFnMeta = { id: serverFnMeta.id };\n let fetcher: AnyFn;\n let resolvedMiddleware: (AnyFunctionMiddleware | AnyRequestMiddleware)[] = [];\n\n const executeServer = async (opts?: Partial<CompiledFetcherFnOptions> & { request?: Request }): Promise<ServerExecutionResult> => {\n const callOpts = normalizeDataOptions(opts) as Partial<CompiledFetcherFnOptions> & { request?: Request };\n const startContext = getStartContext({ throwIfNotFound: false });\n const request = callOpts.request ?? startContext?.request ?? new Request('http://tanstack-router-testing.test/_serverFn');\n const result: ServerFnMiddlewareResult = await runInEnv('server', () =>\n executeMiddleware(resolvedMiddleware, 'server', {\n ...callOpts,\n data: callOpts.data,\n method: nextOptions.method,\n serverFnMeta,\n signal: callOpts.signal ?? new AbortController().signal,\n context: safeObjectMerge(callOpts.context ?? createNullProtoObject(), startContext?.contextAfterGlobalMiddlewares),\n request,\n pathname: getPathnameFromRequest(request),\n } as ServerFnMiddlewareOptions),\n );\n\n return {\n result: result.result,\n error: result.error,\n context: result.sendContext,\n };\n };\n\n const extractedFn = Object.assign(\n async (opts?: CompiledFetcherFnOptions & ServerFnBaseOptions<any, Method>): Promise<unknown> => {\n if (extractedFromTransform) {\n return await extractedFromTransform(opts);\n }\n return await executeServer(opts);\n },\n {\n url: `/_serverFn/${serverFnMeta.id}`,\n serverFnMeta,\n },\n );\n\n const handlerOptions = {\n ...nextOptions,\n extractedFn,\n serverFn,\n };\n resolvedMiddleware = [\n ...((handlerOptions.middleware ?? []) as (AnyFunctionMiddleware | AnyRequestMiddleware)[]),\n createServerFnMiddleware(handlerOptions, () => fetcher),\n ];\n\n fetcher = Object.assign(\n async (opts?: Partial<CompiledFetcherFnOptions>): Promise<unknown> => {\n const callOpts = normalizeDataOptions(opts);\n if (currentEnv() === 'server') {\n const result = await executeServer(callOpts);\n const redirect = parseRedirect(result.error);\n if (redirect) throw redirect;\n if (result.error) throw result.error;\n return result.result;\n }\n\n const result = await runInEnv('client', () =>\n executeMiddleware(resolvedMiddleware, 'client', {\n ...extractedFn,\n ...handlerOptions,\n data: callOpts.data,\n headers: callOpts.headers,\n signal: callOpts.signal ?? new AbortController().signal,\n fetch: callOpts.fetch ?? getStartOptions()?.serverFns?.fetch,\n context: createNullProtoObject(),\n serverFnMeta: clientMeta,\n } as ServerFnMiddlewareOptions),\n );\n\n const redirect = parseRedirect(result.error);\n if (redirect) throw redirect;\n if (result.error) throw result.error;\n return result.result;\n },\n {\n ...extractedFn,\n [TSS_SERVER_FUNCTION]: true,\n method: nextOptions.method,\n __executeServer: executeServer,\n },\n );\n\n registerServerFn(fetcher, serverFn as unknown as AnyFn);\n return fetcher;\n },\n });\n\n return builder;\n };\n\n return makeBuilder(resolvedOptions);\n}) as CreateServerFnShim;\n\nconst createPhaseWrapper =\n (mw: object, phase: 'client' | 'server'): AnyFn =>\n async (ctx: unknown) => {\n const entry = getMiddlewareEntry(mw);\n const impl = phase === 'client' ? (entry?.mockClient ?? entry?.originalClient) : (entry?.mockServer ?? entry?.originalServer);\n if (!impl) return (ctx as { next?: AnyFn }).next?.();\n return impl(ctx as never);\n };\n\nexport const createMiddleware: CreateMiddlewareShim = ((options: { type?: MiddlewareType } | undefined, __opts: Record<string, unknown> | undefined) => {\n const makeBuilder = (resolvedOptions: Record<string, unknown>) => {\n const mw: Record<string, unknown> = {};\n const originalClient = resolvedOptions.client as AnyFn | undefined;\n const originalServer = resolvedOptions.server as AnyFn | undefined;\n const optionsWithWrappedPhases = {\n ...resolvedOptions,\n ...(originalClient ? { client: createPhaseWrapper(mw, 'client') } : {}),\n ...(originalServer ? { server: createPhaseWrapper(mw, 'server') } : {}),\n };\n\n Object.assign(mw, {\n '~types': undefined,\n options: optionsWithWrappedPhases,\n middleware: (middlewares: unknown) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n middleware: middlewares,\n } as never,\n ),\n inputValidator: (inputValidator: unknown) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n inputValidator,\n } as never,\n ),\n client: (client: AnyFn) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n client,\n } as never,\n ),\n server: (server: AnyFn) =>\n createMiddleware(\n {} as never,\n {\n ...resolvedOptions,\n server,\n } as never,\n ),\n });\n\n registerMiddleware(mw, {\n ...(originalClient ? { client: originalClient } : {}),\n ...(originalServer ? { server: originalServer } : {}),\n });\n\n return mw;\n };\n\n return makeBuilder({\n type: 'request' satisfies MiddlewareType,\n ...(__opts ?? options),\n }) as never;\n}) as CreateMiddlewareShim;\n\nexport const createIsomorphicFn = (): IsomorphicFnBase => {\n const makeCallable = <TArgs extends any[], TServer, TClient>(\n serverImpl: ((...args: TArgs) => TServer) | undefined,\n clientImpl?: (...args: TArgs) => TClient,\n ): IsomorphicFn<TArgs, TServer, TClient> => {\n const fn = ((...args: TArgs) => {\n if (currentEnv() === 'server') return serverImpl?.(...args);\n return clientImpl?.(...args);\n }) as IsomorphicFn<TArgs, TServer, TClient>;\n return fn;\n };\n\n const base = (() => {}) as unknown as IsomorphicFnBase;\n return Object.assign(base, {\n server: <TArgs extends any[], TServer>(serverImpl: (...args: TArgs) => TServer): ServerOnlyFn<TArgs, TServer> => {\n const serverOnly = makeCallable<TArgs, TServer, undefined>(serverImpl) as ServerOnlyFn<TArgs, TServer>;\n return Object.assign(serverOnly, {\n client: <TClient>(clientImpl: (...args: TArgs) => TClient) => makeCallable(serverImpl, clientImpl),\n });\n },\n client: <TArgs extends any[], TClient>(clientImpl: (...args: TArgs) => TClient): ClientOnlyFn<TArgs, TClient> => {\n const clientOnly = makeCallable<TArgs, undefined, TClient>(undefined, clientImpl) as ClientOnlyFn<TArgs, TClient>;\n return Object.assign(clientOnly, {\n server: <TServer>(serverImpl: (...args: TArgs) => TServer) => makeCallable(serverImpl, clientImpl),\n });\n },\n });\n};\n\nexport const createServerOnlyFn = <TFn extends AnyFn>(fn: TFn): TFn =>\n ((...args: Parameters<TFn>) => {\n if (currentEnv() === 'client') {\n throw new Error('[tanstack-router-testing] createServerOnlyFn: attempted to call a server-only function in the client test environment.');\n }\n return fn(...args);\n }) as TFn;\n\nexport const createClientOnlyFn = <TFn extends AnyFn>(fn: TFn): TFn =>\n ((...args: Parameters<TFn>) => {\n if (currentEnv() === 'server') {\n throw new Error('[tanstack-router-testing] createClientOnlyFn: attempted to call a client-only function in the server test environment.');\n }\n return fn(...args);\n }) as TFn;\n\nexport const createStart = ((getOptions: () => Promise<Omit<AnyStartInstanceOptions, '~types'>> | Omit<AnyStartInstanceOptions, '~types'>) => {\n const getAndStoreOptions = async () => {\n const options = await toPromise(getOptions());\n setStartOptions(options as AnyStartInstanceOptions);\n return options;\n };\n\n const initialOptions = getOptions();\n if (initialOptions instanceof Promise) {\n void initialOptions.then(options => {\n setStartOptions(options as AnyStartInstanceOptions);\n });\n } else {\n setStartOptions(initialOptions as AnyStartInstanceOptions);\n }\n\n return {\n getOptions: getAndStoreOptions,\n createMiddleware,\n };\n}) as typeof upstreamCreateStart;\n\nexport function useServerFn<T extends (...deps: any[]) => Promise<any>>(serverFn: T): (...args: Parameters<T>) => ReturnType<T> {\n const router = useRouter();\n\n return React.useCallback(\n async (...args: any[]) => {\n try {\n const res = await serverFn(...args);\n\n if (isRedirect(res)) {\n throw res;\n }\n\n return res;\n } catch (error) {\n if (isRedirect(error)) {\n error.options._fromLocation = router.stores.location.get();\n return router.navigate(router.resolveRedirect(error).options);\n }\n\n throw error;\n }\n },\n [router, serverFn],\n ) as any;\n}\n"],"x_google_ignoreList":[0,1,2],"mappings":"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"}
|
package/dist/shim.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as createServerFn, c as useServerFn, i as createMiddleware, n as createClientOnlyFn, o as createServerOnlyFn, r as createIsomorphicFn, s as createStart, t as __setStartOptionsForTesting } from "./shim-
|
|
1
|
+
import { a as createServerFn, c as useServerFn, i as createMiddleware, n as createClientOnlyFn, o as createServerOnlyFn, r as createIsomorphicFn, s as createStart, t as __setStartOptionsForTesting } from "./shim-C-PA0sYH.mjs";
|
|
2
2
|
export * from "@tanstack/start-client-core";
|
|
3
3
|
export { __setStartOptionsForTesting, createClientOnlyFn, createIsomorphicFn, createMiddleware, createServerFn, createServerOnlyFn, createStart, useServerFn };
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Config } from "@tanstack/router-plugin/vite";
|
|
1
2
|
import { Plugin } from "vite";
|
|
2
3
|
|
|
3
4
|
//#region src/vite.d.ts
|
|
@@ -27,6 +28,27 @@ interface TanstackStartTestingOptions {
|
|
|
27
28
|
* @defaultValue `false`
|
|
28
29
|
*/
|
|
29
30
|
readonly rsc?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Additional options forwarded to the underlying `tanstackRouter()` plugin.
|
|
33
|
+
*
|
|
34
|
+
* Explicit top-level options (`routesDirectory`, `generatedRouteTree`) take
|
|
35
|
+
* precedence over values in this object. `target` is always forced to `'react'`.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* tanstackStartTesting({
|
|
40
|
+
* router: {
|
|
41
|
+
* routeFileIgnorePattern: '.*\\.test\\.(ts|tsx)$',
|
|
42
|
+
* routeTreeFileFooter: () => [
|
|
43
|
+
* "declare module '@tanstack/react-start' {",
|
|
44
|
+
* ' interface Register { router: ReturnType<typeof getRouter> }',
|
|
45
|
+
* '}',
|
|
46
|
+
* ],
|
|
47
|
+
* },
|
|
48
|
+
* })
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
readonly router?: Partial<Config>;
|
|
30
52
|
}
|
|
31
53
|
/**
|
|
32
54
|
* Vite/Vitest plugins for TanStack Start tests.
|
|
@@ -34,7 +56,7 @@ interface TanstackStartTestingOptions {
|
|
|
34
56
|
* This keeps route-tree generation on the real TanStack router plugin path
|
|
35
57
|
* while swapping the Start runtime to the in-process testing shim.
|
|
36
58
|
*/
|
|
37
|
-
declare const tanstackStartTesting: (options?: TanstackStartTestingOptions) =>
|
|
59
|
+
declare const tanstackStartTesting: (options?: TanstackStartTestingOptions) => Plugin[];
|
|
38
60
|
//#endregion
|
|
39
61
|
export { TanstackStartTestingOptions, tanstackStartTesting };
|
|
40
62
|
//# sourceMappingURL=vite.d.mts.map
|
package/dist/vite.mjs
CHANGED
|
@@ -7,18 +7,24 @@ import { tanstackRouter } from "@tanstack/router-plugin/vite";
|
|
|
7
7
|
* while swapping the Start runtime to the in-process testing shim.
|
|
8
8
|
*/
|
|
9
9
|
const tanstackStartTesting = (options = {}) => {
|
|
10
|
-
const
|
|
11
|
-
routesDirectory:
|
|
12
|
-
generatedRouteTree:
|
|
10
|
+
const routerPluginOptions = {
|
|
11
|
+
routesDirectory: "src/routes",
|
|
12
|
+
generatedRouteTree: "src/routeTree.gen.ts",
|
|
13
|
+
...options.router,
|
|
14
|
+
...options.routesDirectory !== void 0 ? { routesDirectory: options.routesDirectory } : {},
|
|
15
|
+
...options.generatedRouteTree !== void 0 ? { generatedRouteTree: options.generatedRouteTree } : {},
|
|
13
16
|
target: "react"
|
|
14
|
-
}
|
|
17
|
+
};
|
|
18
|
+
const routerPlugins = tanstackRouter(routerPluginOptions);
|
|
15
19
|
return [
|
|
16
20
|
...Array.isArray(routerPlugins) ? routerPlugins : [routerPlugins],
|
|
21
|
+
tanstackStartBrowserCompat(),
|
|
22
|
+
tanstackStartVirtualStubs(),
|
|
17
23
|
...options.rsc === true ? [tanstackStartRscTestingRuntime()] : [],
|
|
18
24
|
{
|
|
19
25
|
name: "@tanstack/react-start/testing",
|
|
20
26
|
config() {
|
|
21
|
-
const genPath =
|
|
27
|
+
const genPath = routerPluginOptions.generatedRouteTree;
|
|
22
28
|
return {
|
|
23
29
|
...options.aliasReactStart !== false ? { resolve: { alias: [{
|
|
24
30
|
find: /^@tanstack\/react-start$/,
|
|
@@ -30,6 +36,55 @@ const tanstackStartTesting = (options = {}) => {
|
|
|
30
36
|
}
|
|
31
37
|
];
|
|
32
38
|
};
|
|
39
|
+
const STORAGE_CONTEXT_STUB_ID = "\0tanstack-start-storage-context-browser-stub";
|
|
40
|
+
const STORAGE_CONTEXT_STUB_CODE = "export function getStartContext() { return undefined; }\nexport function runWithStartContext(_ctx, fn) { return fn(); }";
|
|
41
|
+
/**
|
|
42
|
+
* Stub `@tanstack/start-storage-context` in browser environments to prevent
|
|
43
|
+
* `node:async_hooks` from crashing Vitest browser mode.
|
|
44
|
+
*
|
|
45
|
+
* @returns A Vite plugin that intercepts the import in client environments and
|
|
46
|
+
* serves a no-op module with matching exports.
|
|
47
|
+
*/
|
|
48
|
+
const tanstackStartBrowserCompat = () => ({
|
|
49
|
+
name: "tanstack-start-testing:browser-compat",
|
|
50
|
+
enforce: "pre",
|
|
51
|
+
config() {
|
|
52
|
+
return { environments: { client: { optimizeDeps: { exclude: ["@tanstack/start-storage-context"] } } } };
|
|
53
|
+
},
|
|
54
|
+
resolveId(id) {
|
|
55
|
+
return this.environment.name === "client" && id === "@tanstack/start-storage-context" ? STORAGE_CONTEXT_STUB_ID : void 0;
|
|
56
|
+
},
|
|
57
|
+
load(id) {
|
|
58
|
+
if (id !== STORAGE_CONTEXT_STUB_ID) return;
|
|
59
|
+
return STORAGE_CONTEXT_STUB_CODE;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const VIRTUAL_MODULE_IDS = new Set([
|
|
63
|
+
"#tanstack-router-entry",
|
|
64
|
+
"#tanstack-start-entry",
|
|
65
|
+
"#tanstack-start-plugin-adapters",
|
|
66
|
+
"#tanstack-start-server-fn-resolver",
|
|
67
|
+
"virtual:tanstack-rsc-ssr-decode",
|
|
68
|
+
"virtual:tanstack-rsc-browser-decode",
|
|
69
|
+
"tanstack-start-manifest:v",
|
|
70
|
+
"tanstack-start-injected-head-scripts:v"
|
|
71
|
+
]);
|
|
72
|
+
/**
|
|
73
|
+
* Resolve all known `#tanstack-*` and `virtual:tanstack-*` module IDs to
|
|
74
|
+
* empty virtual stubs so they don't cause unresolved import errors in tests.
|
|
75
|
+
*
|
|
76
|
+
* @returns A Vite plugin that resolves and loads no-op stubs for TanStack
|
|
77
|
+
* Start's internal virtual modules.
|
|
78
|
+
*/
|
|
79
|
+
const tanstackStartVirtualStubs = () => ({
|
|
80
|
+
name: "tanstack-start-testing:virtual-stubs",
|
|
81
|
+
resolveId(id) {
|
|
82
|
+
return VIRTUAL_MODULE_IDS.has(id) ? `\0${id}` : void 0;
|
|
83
|
+
},
|
|
84
|
+
load(id) {
|
|
85
|
+
return id.startsWith("\0") && VIRTUAL_MODULE_IDS.has(id.slice(1)) ? "export default {}; export {};" : void 0;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
33
88
|
const VIRTUAL_RSC_RUNTIME = "virtual:tanstack-rsc-runtime";
|
|
34
89
|
const RESOLVED_VIRTUAL_RSC_RUNTIME = "\0@tanstack/react-start/testing/rsc-runtime";
|
|
35
90
|
const tanstackStartRscTestingRuntime = () => ({
|
package/dist/vite.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.mjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, UserConfig } from 'vite';\n\nimport { tanstackRouter } from '@tanstack/router-plugin/vite';\n\nexport interface TanstackStartTestingOptions {\n /**\n * Directory holding file-based routes, relative to the Vite root.\n *\n * @defaultValue `'src/routes'`\n */\n readonly routesDirectory?: string;\n /**\n * Output path for the generated route tree, relative to the Vite root.\n *\n * @defaultValue `'src/routeTree.gen.ts'`\n */\n readonly generatedRouteTree?: string;\n /**\n * Whether to alias `@tanstack/react-start` to the test runtime shim.\n *\n * @defaultValue `true`\n */\n readonly aliasReactStart?: boolean;\n /**\n * Install a small test runtime module for TanStack Start RSC imports that\n * need `virtual:tanstack-rsc-runtime` under Vitest.\n *\n * @defaultValue `false`\n */\n readonly rsc?: boolean;\n}\n\n/**\n * Vite/Vitest plugins for TanStack Start tests.\n *\n * This keeps route-tree generation on the real TanStack router plugin path\n * while swapping the Start runtime to the in-process testing shim.\n */\nexport const tanstackStartTesting = (options: TanstackStartTestingOptions = {}):
|
|
1
|
+
{"version":3,"file":"vite.mjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import type { Config } from '@tanstack/router-plugin/vite';\nimport type { Plugin, UserConfig } from 'vite';\n\nimport { tanstackRouter } from '@tanstack/router-plugin/vite';\n\nexport interface TanstackStartTestingOptions {\n /**\n * Directory holding file-based routes, relative to the Vite root.\n *\n * @defaultValue `'src/routes'`\n */\n readonly routesDirectory?: string;\n /**\n * Output path for the generated route tree, relative to the Vite root.\n *\n * @defaultValue `'src/routeTree.gen.ts'`\n */\n readonly generatedRouteTree?: string;\n /**\n * Whether to alias `@tanstack/react-start` to the test runtime shim.\n *\n * @defaultValue `true`\n */\n readonly aliasReactStart?: boolean;\n /**\n * Install a small test runtime module for TanStack Start RSC imports that\n * need `virtual:tanstack-rsc-runtime` under Vitest.\n *\n * @defaultValue `false`\n */\n readonly rsc?: boolean;\n /**\n * Additional options forwarded to the underlying `tanstackRouter()` plugin.\n *\n * Explicit top-level options (`routesDirectory`, `generatedRouteTree`) take\n * precedence over values in this object. `target` is always forced to `'react'`.\n *\n * @example\n * ```ts\n * tanstackStartTesting({\n * router: {\n * routeFileIgnorePattern: '.*\\\\.test\\\\.(ts|tsx)$',\n * routeTreeFileFooter: () => [\n * \"declare module '@tanstack/react-start' {\",\n * ' interface Register { router: ReturnType<typeof getRouter> }',\n * '}',\n * ],\n * },\n * })\n * ```\n */\n readonly router?: Partial<Config>;\n}\n\n/**\n * Vite/Vitest plugins for TanStack Start tests.\n *\n * This keeps route-tree generation on the real TanStack router plugin path\n * while swapping the Start runtime to the in-process testing shim.\n */\nexport const tanstackStartTesting = (options: TanstackStartTestingOptions = {}): Plugin[] => {\n const routerPluginOptions = {\n routesDirectory: 'src/routes',\n generatedRouteTree: 'src/routeTree.gen.ts',\n ...options.router,\n ...(options.routesDirectory !== undefined ? { routesDirectory: options.routesDirectory } : {}),\n ...(options.generatedRouteTree !== undefined ? { generatedRouteTree: options.generatedRouteTree } : {}),\n target: 'react' as const,\n };\n const routerPlugins = tanstackRouter(routerPluginOptions);\n const plugins: Plugin[] = [\n ...(Array.isArray(routerPlugins) ? routerPlugins : [routerPlugins]),\n tanstackStartBrowserCompat(),\n tanstackStartVirtualStubs(),\n ...(options.rsc === true ? [tanstackStartRscTestingRuntime()] : []),\n {\n name: '@tanstack/react-start/testing',\n config(): UserConfig & { test: { setupFiles: readonly string[] } } {\n const genPath = routerPluginOptions.generatedRouteTree;\n return {\n ...(options.aliasReactStart !== false\n ? {\n resolve: {\n alias: [\n {\n find: /^@tanstack\\/react-start$/,\n replacement: '@tanstack-router-testing/react-start-testing/shim',\n },\n ],\n },\n }\n : {}),\n test: {\n setupFiles: [genPath],\n },\n };\n },\n },\n ];\n return plugins;\n};\n\nconst STORAGE_CONTEXT_STUB_ID = '\\0tanstack-start-storage-context-browser-stub';\nconst STORAGE_CONTEXT_STUB_CODE = 'export function getStartContext() { return undefined; }\\nexport function runWithStartContext(_ctx, fn) { return fn(); }';\n\n/**\n * Stub `@tanstack/start-storage-context` in browser environments to prevent\n * `node:async_hooks` from crashing Vitest browser mode.\n *\n * @returns A Vite plugin that intercepts the import in client environments and\n * serves a no-op module with matching exports.\n */\nconst tanstackStartBrowserCompat = (): Plugin => ({\n name: 'tanstack-start-testing:browser-compat',\n enforce: 'pre',\n config() {\n return {\n environments: {\n client: {\n optimizeDeps: {\n exclude: ['@tanstack/start-storage-context'],\n },\n },\n },\n };\n },\n resolveId(id) {\n return this.environment.name === 'client' && id === '@tanstack/start-storage-context' ? STORAGE_CONTEXT_STUB_ID : undefined;\n },\n load(id) {\n if (id !== STORAGE_CONTEXT_STUB_ID) return;\n return STORAGE_CONTEXT_STUB_CODE;\n },\n});\n\nconst VIRTUAL_MODULE_IDS = new Set([\n '#tanstack-router-entry',\n '#tanstack-start-entry',\n '#tanstack-start-plugin-adapters',\n '#tanstack-start-server-fn-resolver',\n 'virtual:tanstack-rsc-ssr-decode',\n 'virtual:tanstack-rsc-browser-decode',\n 'tanstack-start-manifest:v',\n 'tanstack-start-injected-head-scripts:v',\n]);\n\n/**\n * Resolve all known `#tanstack-*` and `virtual:tanstack-*` module IDs to\n * empty virtual stubs so they don't cause unresolved import errors in tests.\n *\n * @returns A Vite plugin that resolves and loads no-op stubs for TanStack\n * Start's internal virtual modules.\n */\nconst tanstackStartVirtualStubs = (): Plugin => ({\n name: 'tanstack-start-testing:virtual-stubs',\n resolveId(id) {\n return VIRTUAL_MODULE_IDS.has(id) ? `\\0${id}` : undefined;\n },\n load(id) {\n return id.startsWith('\\0') && VIRTUAL_MODULE_IDS.has(id.slice(1)) ? 'export default {}; export {};' : undefined;\n },\n});\n\nconst VIRTUAL_RSC_RUNTIME = 'virtual:tanstack-rsc-runtime';\nconst RESOLVED_VIRTUAL_RSC_RUNTIME = '\\0@tanstack/react-start/testing/rsc-runtime';\n\nconst tanstackStartRscTestingRuntime = (): Plugin => ({\n name: '@tanstack/react-start/testing-rsc-runtime',\n resolveId(id) {\n return id === VIRTUAL_RSC_RUNTIME ? RESOLVED_VIRTUAL_RSC_RUNTIME : undefined;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_RSC_RUNTIME) return;\n return `\n import ReactDOMServer from 'react-dom/server';\n\n export function renderToReadableStream(node) {\n const html = ReactDOMServer.renderToString(node);\n const encoder = new TextEncoder();\n return new ReadableStream({\n start(controller) {\n controller.enqueue(encoder.encode(html));\n controller.close();\n }\n });\n }\n `;\n },\n});\n"],"mappings":";;;;;;;;AA4DA,MAAa,wBAAwB,UAAuC,EAAE,KAAe;CAC3F,MAAM,sBAAsB;EAC1B,iBAAiB;EACjB,oBAAoB;EACpB,GAAG,QAAQ;EACX,GAAI,QAAQ,oBAAoB,KAAA,IAAY,EAAE,iBAAiB,QAAQ,iBAAiB,GAAG,EAAE;EAC7F,GAAI,QAAQ,uBAAuB,KAAA,IAAY,EAAE,oBAAoB,QAAQ,oBAAoB,GAAG,EAAE;EACtG,QAAQ;EACT;CACD,MAAM,gBAAgB,eAAe,oBAAoB;AA8BzD,QAAO;EA5BL,GAAI,MAAM,QAAQ,cAAc,GAAG,gBAAgB,CAAC,cAAc;EAClE,4BAA4B;EAC5B,2BAA2B;EAC3B,GAAI,QAAQ,QAAQ,OAAO,CAAC,gCAAgC,CAAC,GAAG,EAAE;EAClE;GACE,MAAM;GACN,SAAmE;IACjE,MAAM,UAAU,oBAAoB;AACpC,WAAO;KACL,GAAI,QAAQ,oBAAoB,QAC5B,EACE,SAAS,EACP,OAAO,CACL;MACE,MAAM;MACN,aAAa;MACd,CACF,EACF,EACF,GACD,EAAE;KACN,MAAM,EACJ,YAAY,CAAC,QAAQ,EACtB;KACF;;GAEJ;EAEW;;AAGhB,MAAM,0BAA0B;AAChC,MAAM,4BAA4B;;;;;;;;AASlC,MAAM,oCAA4C;CAChD,MAAM;CACN,SAAS;CACT,SAAS;AACP,SAAO,EACL,cAAc,EACZ,QAAQ,EACN,cAAc,EACZ,SAAS,CAAC,kCAAkC,EAC7C,EACF,EACF,EACF;;CAEH,UAAU,IAAI;AACZ,SAAO,KAAK,YAAY,SAAS,YAAY,OAAO,oCAAoC,0BAA0B,KAAA;;CAEpH,KAAK,IAAI;AACP,MAAI,OAAO,wBAAyB;AACpC,SAAO;;CAEV;AAED,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;AASF,MAAM,mCAA2C;CAC/C,MAAM;CACN,UAAU,IAAI;AACZ,SAAO,mBAAmB,IAAI,GAAG,GAAG,KAAK,OAAO,KAAA;;CAElD,KAAK,IAAI;AACP,SAAO,GAAG,WAAW,KAAK,IAAI,mBAAmB,IAAI,GAAG,MAAM,EAAE,CAAC,GAAG,kCAAkC,KAAA;;CAEzG;AAED,MAAM,sBAAsB;AAC5B,MAAM,+BAA+B;AAErC,MAAM,wCAAgD;CACpD,MAAM;CACN,UAAU,IAAI;AACZ,SAAO,OAAO,sBAAsB,+BAA+B,KAAA;;CAErE,KAAK,IAAI;AACP,MAAI,OAAO,6BAA8B;AACzC,SAAO;;;;;;;;;;;;;;;CAeV"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack-router-testing/react-start-testing",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Upstream-shaped test helpers for @tanstack/react-start: direct server function tests, mocks, env control, and Vitest wiring.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./dist/index.d.mts",
|
|
31
31
|
"import": "./dist/index.mjs"
|
|
32
32
|
},
|
|
33
|
+
"./browser": {
|
|
34
|
+
"types": "./dist/browser.d.mts",
|
|
35
|
+
"import": "./dist/browser.mjs"
|
|
36
|
+
},
|
|
33
37
|
"./shim": {
|
|
34
38
|
"types": "./dist/shim.d.mts",
|
|
35
39
|
"import": "./dist/shim.mjs"
|
|
@@ -47,7 +51,7 @@
|
|
|
47
51
|
"@tanstack/start-client-core": "1.167.18",
|
|
48
52
|
"@tanstack/start-fn-stubs": "1.161.6",
|
|
49
53
|
"@tanstack/start-storage-context": "1.166.30",
|
|
50
|
-
"@tanstack-router-testing/router-testing-core": "0.0
|
|
54
|
+
"@tanstack-router-testing/router-testing-core": "0.1.0"
|
|
51
55
|
},
|
|
52
56
|
"devDependencies": {
|
|
53
57
|
"@tanstack/react-router": "1.168.24",
|