Skip to content

Commit 097d718

Browse files
authored
fix: allow fetch in remote function without emitting a warning (#14610)
1 parent 7fe3895 commit 097d718

File tree

5 files changed

+46
-33
lines changed

5 files changed

+46
-33
lines changed

.changeset/weak-rings-open.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: allow `fetch` in remote function without emitting a warning

packages/kit/src/runtime/app/server/remote/shared.js

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @import { RequestEvent } from '@sveltejs/kit' */
2-
/** @import { ServerHooks, MaybePromise, RequestState, RemoteInfo } from 'types' */
2+
/** @import { ServerHooks, MaybePromise, RequestState, RemoteInfo, RequestStore } from 'types' */
33
import { parse } from 'devalue';
44
import { error } from '@sveltejs/kit';
55
import { with_request_store, get_request_store } from '@sveltejs/kit/internal/server';
@@ -103,42 +103,48 @@ export function parse_remote_response(data, transport) {
103103
* @param {(arg?: any) => T} fn
104104
*/
105105
export async function run_remote_function(event, state, allow_cookies, arg, validate, fn) {
106-
/** @type {RequestEvent} */
107-
const cleansed = {
108-
...event,
109-
setHeaders: () => {
110-
throw new Error('setHeaders is not allowed in remote functions');
111-
},
112-
cookies: {
113-
...event.cookies,
114-
set: (name, value, opts) => {
115-
if (!allow_cookies) {
116-
throw new Error('Cannot set cookies in `query` or `prerender` functions');
117-
}
118-
119-
if (opts.path && !opts.path.startsWith('/')) {
120-
throw new Error('Cookies set in remote functions must have an absolute path');
121-
}
122-
123-
return event.cookies.set(name, value, opts);
106+
/** @type {RequestStore} */
107+
const store = {
108+
event: {
109+
...event,
110+
setHeaders: () => {
111+
throw new Error('setHeaders is not allowed in remote functions');
124112
},
125-
delete: (name, opts) => {
126-
if (!allow_cookies) {
127-
throw new Error('Cannot delete cookies in `query` or `prerender` functions');
113+
cookies: {
114+
...event.cookies,
115+
set: (name, value, opts) => {
116+
if (!allow_cookies) {
117+
throw new Error('Cannot set cookies in `query` or `prerender` functions');
118+
}
119+
120+
if (opts.path && !opts.path.startsWith('/')) {
121+
throw new Error('Cookies set in remote functions must have an absolute path');
122+
}
123+
124+
return event.cookies.set(name, value, opts);
125+
},
126+
delete: (name, opts) => {
127+
if (!allow_cookies) {
128+
throw new Error('Cannot delete cookies in `query` or `prerender` functions');
129+
}
130+
131+
if (opts.path && !opts.path.startsWith('/')) {
132+
throw new Error('Cookies deleted in remote functions must have an absolute path');
133+
}
134+
135+
return event.cookies.delete(name, opts);
128136
}
129-
130-
if (opts.path && !opts.path.startsWith('/')) {
131-
throw new Error('Cookies deleted in remote functions must have an absolute path');
132-
}
133-
134-
return event.cookies.delete(name, opts);
135137
}
138+
},
139+
state: {
140+
...state,
141+
is_in_remote_function: true
136142
}
137143
};
138144

139145
// In two parts, each with_event, so that runtimes without async local storage can still get the event at the start of the function
140-
const validated = await with_request_store({ event: cleansed, state }, () => validate(arg));
141-
return with_request_store({ event: cleansed, state }, () => fn(validated));
146+
const validated = await with_request_store(store, () => validate(arg));
147+
return with_request_store(store, () => fn(validated));
142148
}
143149

144150
/**

packages/kit/src/runtime/server/page/render.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js';
1313
import { SCHEME } from '../../../utils/url.js';
1414
import { create_server_routing_response, generate_route_object } from './server_routing.js';
1515
import { add_resolution_suffix } from '../../pathname.js';
16-
import { with_request_store } from '@sveltejs/kit/internal/server';
16+
import { try_get_request_store, with_request_store } from '@sveltejs/kit/internal/server';
1717
import { text_encoder } from '../../utils.js';
1818
import { get_global_name } from '../utils.js';
1919
import { create_remote_cache_key } from '../../shared.js';
@@ -190,7 +190,7 @@ export async function render_response({
190190
throw new Error(
191191
`Cannot call \`fetch\` eagerly during server-side rendering with relative URL (${info}) — put your \`fetch\` calls inside \`onMount\` or a \`load\` function instead`
192192
);
193-
} else if (!warned) {
193+
} else if (!warned && !try_get_request_store()?.state.is_in_remote_function) {
194194
console.warn(
195195
'Avoid calling `fetch` eagerly during server-side rendering — put your `fetch` calls inside `onMount` or a `load` function instead'
196196
);

packages/kit/src/runtime/server/respond.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ export async function internal_respond(request, options, manifest, state) {
148148
handleValidationError: options.hooks.handleValidationError,
149149
tracing: {
150150
record_span
151-
}
151+
},
152+
is_in_remote_function: false
152153
};
153154

154155
/** @type {import('@sveltejs/kit').RequestEvent} */

packages/kit/src/types/internal.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ export interface RequestState {
604604
tracing: {
605605
record_span: RecordSpan;
606606
};
607+
is_in_remote_function: boolean;
607608
form_instances?: Map<any, any>;
608609
remote_data?: Map<RemoteInfo, Record<string, MaybePromise<any>>>;
609610
refreshes?: Record<string, Promise<any>>;

0 commit comments

Comments
 (0)