Skip to content

Commit

Permalink
[chore] separate RequestHeaders and ResponseHeaders types
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Aug 19, 2021
1 parent 23ff8b5 commit 034fef7
Show file tree
Hide file tree
Showing 18 changed files with 62 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .changeset/empty-donuts-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

[chore] separate RequestHeaders and ResponseHeaders types
2 changes: 1 addition & 1 deletion packages/adapter-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@sveltejs/kit": "workspace:*",
"c8": "^7.7.2",
"compression": "^1.7.4",
"node-fetch": "^3.0.0-beta.9",
"node-fetch": "^3.0.0-beta.10",
"polka": "^1.0.0-next.17",
"rollup": "^2.55.0",
"sirv": "^1.0.14",
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"locate-character": "^2.0.5",
"marked": "^2.0.3",
"mime": "^2.5.2",
"node-fetch": "^3.0.0-beta.9",
"node-fetch": "^3.0.0-beta.10",
"port-authority": "^1.1.2",
"rimraf": "^3.0.2",
"rollup": "^2.55.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/adapt/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export async function prerender({ cwd, out, log, config, build_data, fallback, a
mkdirp(dirname(file));

if (response_type === REDIRECT) {
const { location } = headers;
const location = /** @type {string} */ (headers.location);

log.warn(`${rendered.status} ${path} -> ${location}`);
writeFileSync(file, `<meta http-equiv="refresh" content="0;url=${encodeURI(location)}">`);
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ async function create_handler(vite, config, dir, cwd, get_manifest) {

const rendered = await respond(
{
headers: /** @type {import('types/helper').Headers} */ (req.headers),
headers: /** @type {import('types/helper').RequestHeaders} */ (req.headers),
method: req.method,
host,
path: parsed.pathname.replace(config.kit.paths.base, ''),
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export async function preview({
host: /** @type {string} */ (config.kit.host ||
req.headers[config.kit.hostHeader || 'host']),
method: req.method,
headers: /** @type {import('types/helper').Headers} */ (req.headers),
headers: /** @type {import('types/helper').RequestHeaders} */ (req.headers),
path: parsed.pathname.replace(config.kit.paths.base, ''),
query: parsed.searchParams,
rawBody: body
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function render_endpoint(request, route, match) {
let { status = 200, body, headers = {} } = response;

headers = lowercase_keys(headers);
const type = headers['content-type'];
const type = /** @type {string} */ (headers['content-type']);

const is_type_textual = is_content_type_textual(type);

Expand Down
3 changes: 2 additions & 1 deletion packages/kit/src/runtime/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export async function respond(incoming, options, state = {}) {
if (response) {
// inject ETags for 200 responses
if (response.status === 200) {
if (!/(no-store|immutable)/.test(response.headers['cache-control'])) {
const cache_control = /** @type {string} */ (response.headers['cache-control']);
if (!/(no-store|immutable)/.test(cache_control)) {
const etag = `"${hash(response.body || '')}"`;

if (request.headers['if-none-match'] === etag) {
Expand Down
11 changes: 8 additions & 3 deletions packages/kit/src/runtime/server/page/load_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ export async function load_node({
} else if (resolved.startsWith('/') && !resolved.startsWith('//')) {
const relative = resolved;

const headers = /** @type {import('types/helper').Headers} */ ({ ...opts.headers });
const headers = /** @type {import('types/helper').RequestHeaders} */ ({
...opts.headers
});

// TODO: fix type https://github.com/node-fetch/node-fetch/issues/1113
if (opts.credentials !== 'omit') {
Expand Down Expand Up @@ -164,9 +166,12 @@ export async function load_node({
state.prerender.dependencies.set(relative, rendered);
}

// Set-Cookie not available to be set in `fetch` and that's the only header value that
// can be an array so we know we have only simple values
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
response = new Response(rendered.body, {
status: rendered.status,
headers: rendered.headers
headers: /** @type {Record<string,string>} */ (rendered.headers)
});
}
} else {
Expand Down Expand Up @@ -211,7 +216,7 @@ export async function load_node({
async function text() {
const body = await response.text();

/** @type {import('types/helper').Headers} */
/** @type {import('types/helper').ResponseHeaders} */
const headers = {};
for (const [key, value] of response.headers) {
if (key !== 'etag' && key !== 'set-cookie') headers[key] = value;
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/page/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export async function render_response({
.join('\n\n\t\t\t')}
`.replace(/^\t{2}/gm, '');

/** @type {import('types/helper').Headers} */
/** @type {import('types/helper').ResponseHeaders} */
const headers = {
'content-type': 'text/html'
};
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/parse_body/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { read_only_form_data } from './read_only_form_data.js';

/**
* @param {import('types/helper').RawBody} raw
* @param {import('types/helper').Headers} headers
* @param {import('types/helper').RequestHeaders} headers
*/
export function parse_body(raw, headers) {
if (!raw) return raw;
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/runtime/server/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @param {Record<string, string>} obj */
/** @param {Record<string, any>} obj */
export function lowercase_keys(obj) {
/** @type {Record<string, string>} */
/** @type {Record<string, any>} */
const clone = {};

for (const key in obj) {
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/test/apps/basics/src/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const handle = sequence(
...response,
headers: {
...response.headers,
'Set-Cookie': 'name=SvelteKit; path=/; HttpOnly'
'set-cookie': 'name=SvelteKit; path=/; HttpOnly'
}
};
}
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/types/endpoint.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ServerRequest } from './hooks';
import { Headers, MaybePromise } from './helper';
import { MaybePromise, ResponseHeaders } from './helper';

type ToJSON = { toJSON(...args: any[]): JSONValue };
type JSONValue = Exclude<JSONResponse, ToJSON>;
Expand All @@ -16,7 +16,7 @@ type DefaultBody = JSONResponse | Uint8Array;

export interface EndpointOutput<Body extends DefaultBody = DefaultBody> {
status?: number;
headers?: Headers;
headers?: ResponseHeaders;
body?: Body;
}

Expand Down
9 changes: 4 additions & 5 deletions packages/kit/types/helper.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ export type ParameterizedBody<Body = unknown> = Body extends FormData
? ReadOnlyFormData
: (string | RawBody | ReadOnlyFormData) & Body;

// TODO we want to differentiate between request headers, which
// always follow this type, and response headers, in which
// 'set-cookie' is a `string[]` (or at least `string | string[]`)
// but this can't happen until TypeScript 4.3
export type Headers = Record<string, string>;
export type RequestHeaders = Record<string, string>;

/** Only value that can be an array is set-cookie. For everything else we assume string value */
export type ResponseHeaders = Record<string, string | string[]>;

export type Location<Params extends Record<string, string> = Record<string, string>> = {
host: string;
Expand Down
13 changes: 10 additions & 3 deletions packages/kit/types/hooks.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { Headers, Location, MaybePromise, ParameterizedBody, RawBody } from './helper';
import {
Location,
MaybePromise,
ParameterizedBody,
RawBody,
RequestHeaders,
ResponseHeaders
} from './helper';

export type StrictBody = string | Uint8Array;

export interface ServerRequest<Locals = Record<string, any>, Body = unknown> extends Location {
method: string;
headers: Headers;
headers: RequestHeaders;
rawBody: RawBody;
body: ParameterizedBody<Body>;
locals: Locals;
}

export interface ServerResponse {
status: number;
headers: Headers;
headers: ResponseHeaders;
body?: StrictBody;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/kit/types/internal.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RequestHandler } from './endpoint';
import { Headers, Location, ParameterizedBody, RawBody } from './helper';
import { Location, ParameterizedBody, RawBody, RequestHeaders } from './helper';
import {
ExternalFetch,
GetSession,
Expand All @@ -14,7 +14,7 @@ type PageId = string;

export interface Incoming extends Omit<Location, 'params'> {
method: string;
headers: Headers;
headers: RequestHeaders;
rawBody: RawBody;
body?: ParameterizedBody;
}
Expand Down
36 changes: 18 additions & 18 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 034fef7

Please sign in to comment.