/
request.ts
86 lines (75 loc) · 2.68 KB
/
request.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import type { IncomingHttpHeaders } from 'node:http';
import type { Logger } from './logger/core.js';
import { appendForwardSlash, prependForwardSlash } from './path.js';
type HeaderType = Headers | Record<string, any> | IncomingHttpHeaders;
type RequestBody = ArrayBuffer | Blob | ReadableStream | URLSearchParams | FormData;
export interface CreateRequestOptions {
base: string;
url: URL | string;
clientAddress?: string | undefined;
headers: HeaderType;
method?: string;
body?: RequestBody | undefined;
logger: Logger;
locals?: object | undefined;
/**
* Whether the request is being created for a static build or for a prerendered page within a hybrid/SSR build, or for emulating one of those in dev mode.
*
* When `true`, the request will not include search parameters or body, and warn when headers are accessed.
*
* @default false
*/
staticLike?: boolean;
}
const clientAddressSymbol = Symbol.for('astro.clientAddress');
const clientLocalsSymbol = Symbol.for('astro.locals');
export function createRequest({
base,
url,
headers,
clientAddress,
method = 'GET',
body = undefined,
logger,
locals,
staticLike = false,
}: CreateRequestOptions): Request {
// headers are made available on the created request only if the request is for a page that will be on-demand rendered
const headersObj = staticLike
? undefined
: headers instanceof Headers
? headers
: new Headers(Object.entries(headers as Record<string, any>));
if (typeof url === 'string') url = new URL(url);
const imageEndpoint = prependForwardSlash(appendForwardSlash(base)) + '_image';
// HACK! astro:assets uses query params for the injected route in `dev`
if (staticLike && url.pathname !== imageEndpoint) {
url.search = '';
}
const request = new Request(url, {
method: method,
headers: headersObj,
// body is made available only if the request is for a page that will be on-demand rendered
body: staticLike ? null : body,
});
if (staticLike) {
// Warn when accessing headers in SSG mode
const _headers = request.headers;
const headersDesc = Object.getOwnPropertyDescriptor(request, 'headers') || {};
Object.defineProperty(request, 'headers', {
...headersDesc,
get() {
logger.warn(
null,
`\`Astro.request.headers\` is not available in "static" output mode. To enable header access: set \`output: "server"\` or \`output: "hybrid"\` in your config file.`
);
return _headers;
},
});
} else if (clientAddress) {
// clientAddress is stored to be read by RenderContext, only if the request is for a page that will be on-demand rendered
Reflect.set(request, clientAddressSymbol, clientAddress);
}
Reflect.set(request, clientLocalsSymbol, locals ?? {});
return request;
}