Skip to content

Commit

Permalink
adding cookies to api route response [simple result] (#5060)
Browse files Browse the repository at this point in the history
* adding cookies to the an api route response, also when returning a simple result

* in dev server, convert a simple endpoint result into a response object

Co-authored-by: AirBorne04 <unknown>
Co-authored-by: AirBorne04 <>
Co-authored-by: Matthew Phillips <matthew@skypack.dev>
  • Loading branch information
AirBorne04 and matthewp authored Oct 18, 2022
1 parent 04ce7f4 commit 5923dd7
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-cougars-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

api routes: adding cookies to the response, also when returning a simple result
2 changes: 0 additions & 2 deletions examples/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@
"astro": "astro",
"server": "node dist/server/entry.mjs"
},
"devDependencies": {},
"dependencies": {
"astro": "^1.5.0",
"svelte": "^3.48.0",
"@astrojs/svelte": "^1.0.2",
"@astrojs/node": "^2.0.0",
"concurrently": "^7.2.1",
"lightcookie": "^1.0.25",
"unocss": "^0.15.6",
"vite-imagetools": "^4.0.4"
}
Expand Down
1 change: 1 addition & 0 deletions examples/ssr/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async function get<T>(
): Promise<T> {
const response = await fetch(`${getOrigin(incomingReq)}${endpoint}`, {
credentials: 'same-origin',
headers: incomingReq.headers,
});
if (!response.ok) {
// TODO make this better...
Expand Down
7 changes: 0 additions & 7 deletions examples/ssr/src/models/user.ts

This file was deleted.

12 changes: 5 additions & 7 deletions examples/ssr/src/pages/api/cart.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { APIContext } from 'astro';
import lightcookie from 'lightcookie';
import { userCartItems } from '../../models/session';

export function get({ request }: APIContext) {
let cookie = request.headers.get('cookie');
let userId = cookie ? lightcookie.parse(cookie)['user-id'] : '1'; // default for testing
export function get({ cookies }: APIContext) {
let userId = cookies.get('user-id').value;

if (!userId || !userCartItems.has(userId)) {
return {
body: JSON.stringify({ items: [] }),
Expand All @@ -23,11 +22,10 @@ interface AddToCartItem {
name: string;
}

export async function post({ request }: APIContext) {
export async function post({ cookies, request }: APIContext) {
const item: AddToCartItem = await request.json();

let cookie = request.headers.get('cookie');
let userId = lightcookie.parse(cookie)['user-id'];
let userId = cookies.get('user-id').value;

if (!userCartItems.has(userId)) {
userCartItems.set(userId, new Map());
Expand Down
3 changes: 1 addition & 2 deletions examples/ssr/src/pages/cart.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
import Header from '../components/Header.astro';
import Container from '../components/Container.astro';
import { getCart } from '../api';
import { isLoggedIn } from '../models/user';
if (!isLoggedIn(Astro.request)) {
if (!Astro.cookies.get('user-id').value) {
return Astro.redirect('/');
}
Expand Down
27 changes: 27 additions & 0 deletions examples/ssr/src/pages/login.astro
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@ import Container from '../components/Container.astro';
font-size: 36px;
}
</style>

<script type="module" is:inline>
document.addEventListener('DOMContentLoaded', () => {
console.log('loaded');
document.querySelector('form').addEventListener('submit', (e) => {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
const data = Object.fromEntries(formData);

fetch('/login.form.async', {
method: 'POST',
body: JSON.stringify(data),
})
.then((res) => res.json())
.then((data) => {
document.querySelector("#result").innerHTML = "Progressive login was successful! you will be redirected to the store in 3 seconds";
setTimeout(
() => location.href = "/",
3000
);

});
});
});
</script>
</head>
<body>
<Header />
Expand All @@ -26,6 +52,7 @@ import Container from '../components/Container.astro';

<input type="submit" value="Submit" />
</form>
<div id="result"></div>
</Container>
</body>
</html>
16 changes: 16 additions & 0 deletions examples/ssr/src/pages/login.form.async.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { APIContext, APIRoute } from 'astro';

export const post: APIRoute = ({ cookies, params, request }: APIContext) => {
// add a new cookie
cookies.set('user-id', '1', {
path: '/',
maxAge: 2592000,
});

return {
body: JSON.stringify({
ok: true,
user: 1,
}),
};
};
9 changes: 0 additions & 9 deletions examples/ssr/src/pages/login.form.js

This file was deleted.

16 changes: 16 additions & 0 deletions examples/ssr/src/pages/login.form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { APIContext } from 'astro';

export function post({ cookies, params, request }: APIContext) {
// add a new cookie
cookies.set('user-id', '1', {
path: '/',
maxAge: 2592000,
});

return new Response(null, {
status: 301,
headers: {
Location: '/',
},
});
}
8 changes: 6 additions & 2 deletions packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { LogOptions } from '../logger/core.js';
import type { RouteInfo, SSRManifest as Manifest } from './types';

import mime from 'mime';
import { getSetCookiesFromResponse } from '../cookies/index.js';
import { attachToResponse, getSetCookiesFromResponse } from '../cookies/index.js';
import { call as callEndpoint } from '../endpoint/index.js';
import { consoleLogDestination } from '../logger/console.js';
import { error } from '../logger/core.js';
Expand Down Expand Up @@ -236,10 +236,14 @@ export class App {
}
const bytes = this.#encoder.encode(body);
headers.set('Content-Length', bytes.byteLength.toString());
return new Response(bytes, {

const response = new Response(bytes, {
status: 200,
headers,
});

attachToResponse(response, result.cookies);
return response;
}
}
}
2 changes: 2 additions & 0 deletions packages/astro/src/core/endpoint/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type EndpointCallResult =
type: 'simple';
body: string;
encoding?: BufferEncoding;
cookies: AstroCookies;
}
| {
type: 'response';
Expand Down Expand Up @@ -109,5 +110,6 @@ export async function call(
type: 'simple',
body: response.body,
encoding: response.encoding,
cookies: context.cookies,
};
}
12 changes: 9 additions & 3 deletions packages/astro/src/vite-plugin-astro-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { AstroSettings, ManifestData } from '../@types/astro';
import { DevelopmentEnvironment, SSROptions } from '../core/render/dev/index';

import { Readable } from 'stream';
import { getSetCookiesFromResponse } from '../core/cookies/index.js';
import { attachToResponse, getSetCookiesFromResponse } from '../core/cookies/index.js';
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
import {
collectErrorMetadata,
Expand Down Expand Up @@ -378,8 +378,14 @@ async function handleRoute(
if (computedMimeType) {
contentType = computedMimeType;
}
res.writeHead(200, { 'Content-Type': `${contentType};charset=utf-8` });
res.end(result.body);
const response = new Response(result.body, {
status: 200,
headers: {
'Content-Type': `${contentType};charset=utf-8`,
},
});
attachToResponse(response, result.cookies);
await writeWebResponse(res, response);
}
} else {
const result = await renderPage(options);
Expand Down
6 changes: 0 additions & 6 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 5923dd7

Please sign in to comment.