Skip to content

Upgrade SvelteKit and resolve breaking changes #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions package-lock.json

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

6 changes: 3 additions & 3 deletions src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.png" />
<meta name="description" content="Svelte demo app" />
<link rel="icon" href="%svelte.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

%svelte.head%
</head>
<body>
<div id="svelte">%svelte.body%</div>
<div>%svelte.body%</div>
</body>
</html>
21 changes: 11 additions & 10 deletions src/hooks.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import cookie from 'cookie';
import { v4 as uuid } from '@lukeed/uuid';

export const handle = async ({ request, resolve }) => {
const cookies = cookie.parse(request.headers.cookie || '');
request.locals.userid = cookies.userid || uuid();
export const handle = async ({ event, resolve }) => {
const cookies = cookie.parse(event.request.headers.get('cookie') || '');
event.locals.userid = cookies.userid || uuid();

// TODO https://github.com/sveltejs/kit/issues/1046
if (request.url.searchParams.has('_method')) {
request.method = request.url.searchParams.get('_method').toUpperCase();
}

const response = await resolve(request);
const response = await resolve(event);

if (!cookies.userid) {
// if this is the first time the user has visited this app,
// set a cookie so that we recognise them when they return
response.headers['set-cookie'] = `userid=${request.locals.userid}; Path=/; HttpOnly`;
response.headers.set(
'set-cookie',
cookie.serialize('userid', event.locals.userid, {
path: '/',
httpOnly: true
})
);
}

return response;
Expand Down
10 changes: 7 additions & 3 deletions src/lib/Counter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

<div class="counter-viewport">
<div class="counter-digits" style="transform: translate(0, {100 * offset}%)">
<strong style="top: -100%" aria-hidden="true">{Math.floor($displayed_count + 1)}</strong>
<strong class="hidden" aria-hidden="true">{Math.floor($displayed_count + 1)}</strong>
<strong>{Math.floor($displayed_count)}</strong>
</div>
</div>
Expand Down Expand Up @@ -79,13 +79,12 @@

.counter-viewport strong {
position: absolute;
display: block;
display: flex;
width: 100%;
height: 100%;
font-weight: 400;
color: var(--accent-color);
font-size: 4rem;
display: flex;
align-items: center;
justify-content: center;
}
Expand All @@ -95,4 +94,9 @@
width: 100%;
height: 100%;
}

.hidden {
top: -100%;
user-select: none;
}
</style>
10 changes: 7 additions & 3 deletions src/lib/header/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
</svg>
<ul>
<li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li>
<li class:active={$page.url.pathname === '/about'}><a sveltekit:prefetch href="/about">About</a></li>
<li class:active={$page.url.pathname === '/todos'}><a sveltekit:prefetch href="/todos">Todos</a></li>
<li class:active={$page.url.pathname === '/about'}>
<a sveltekit:prefetch href="/about">About</a>
</li>
<li class:active={$page.url.pathname === '/todos'}>
<a sveltekit:prefetch href="/todos">Todos</a>
</li>
</ul>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
Expand Down Expand Up @@ -109,7 +113,7 @@
font-weight: 700;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 10%;
letter-spacing: 0.1em;
text-decoration: none;
transition: color 0.2s linear;
}
Expand Down
14 changes: 8 additions & 6 deletions src/routes/todos/[uid].json.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { api } from './_api';

// PATCH /todos/:uid.json
export const patch = async (request) => {
return api(request, `todos/${request.locals.userid}/${request.params.uid}`, {
text: request.body.get('text'),
done: request.body.has('done') ? !!request.body.get('done') : undefined
export const patch = async (event) => {
const data = await event.request.formData();

return api(event, `todos/${event.locals.userid}/${event.params.uid}`, {
text: data.get('text'),
done: data.has('done') ? !!data.get('done') : undefined
});
};

// DELETE /todos/:uid.json
export const del = async (request) => {
return api(request, `todos/${request.locals.userid}/${request.params.uid}`);
export const del = async (event) => {
return api(event, `todos/${event.locals.userid}/${event.params.uid}`);
};
12 changes: 8 additions & 4 deletions src/routes/todos/_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@

const base = 'https://api.svelte.dev';

export async function api(request, resource, data) {
export async function api(event, resource, data) {
// user must have a cookie set
if (!request.locals.userid) {
if (!event.locals.userid) {
return { status: 401 };
}

const res = await fetch(`${base}/${resource}`, {
method: request.method,
method: event.request.method,
headers: {
'content-type': 'application/json'
},
Expand All @@ -29,7 +29,11 @@ export async function api(request, resource, data) {
// behaviour is to show the URL corresponding to the form's "action"
// attribute. in those cases, we want to redirect them back to the
// /todos page, rather than showing the response
if (res.ok && request.method !== 'GET' && request.headers.accept !== 'application/json') {
if (
res.ok &&
event.request.method !== 'GET' &&
event.request.headers.get('accept') !== 'application/json'
) {
return {
status: 303,
headers: {
Expand Down
14 changes: 8 additions & 6 deletions src/routes/todos/index.json.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { api } from './_api';

// GET /todos.json
export const get = async (request) => {
// request.locals.userid comes from src/hooks.js
const response = await api(request, `todos/${request.locals.userid}`);
export const get = async (event) => {
// event.locals.userid comes from src/hooks.js
const response = await api(event, `todos/${event.locals.userid}`);

if (response.status === 404) {
// user hasn't created a todo list.
Expand All @@ -15,13 +15,15 @@ export const get = async (request) => {
};

// POST /todos.json
export const post = async (request) => {
const response = await api(request, `todos/${request.locals.userid}`, {
export const post = async (event) => {
const data = await event.request.formData();

const response = await api(event, `todos/${event.locals.userid}`, {
// because index.svelte posts a FormData object,
// request.body is _also_ a (readonly) FormData
// object, which allows us to get form data
// with the `body.get(key)` method
text: request.body.get('text')
text: data.get('text')
});

return response;
Expand Down
9 changes: 5 additions & 4 deletions src/routes/todos/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
animate:flip={{ duration: 200 }}
>
<form
action="/todos/{todo.uid}.json?_method=patch"
action="/todos/{todo.uid}.json?_method=PATCH"
method="post"
use:enhance={{
pending: (data) => {
Expand All @@ -83,7 +83,7 @@

<form
class="text"
action="/todos/{todo.uid}.json?_method=patch"
action="/todos/{todo.uid}.json?_method=PATCH"
method="post"
use:enhance={{
result: patch
Expand All @@ -94,15 +94,16 @@
</form>

<form
action="/todos/{todo.uid}.json?_method=delete"
action="/todos/{todo.uid}.json?_method=DELETE"
method="post"
use:enhance={{
pending: () => (todo.pending_delete = true),
result: () => {
todos = todos.filter((t) => t.uid !== todo.uid);
}
}}
>
<button class="delete" aria-label="Delete todo" />
<button class="delete" aria-label="Delete todo" disabled={todo.pending_delete} />
</form>
</div>
{/each}
Expand Down
9 changes: 6 additions & 3 deletions svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import node from '@sveltejs/adapter-node';

const config = {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
adapter: node()
adapter: node(),

// Override http methods in the Todo forms
methodOverride: {
allowed: ['PATCH', 'DELETE']
}
}
};

Expand Down