Skip to content

Commit 64a75d2

Browse files
committed
next 16 update, security fixes and pwa update
1 parent f2fb381 commit 64a75d2

File tree

19 files changed

+1209
-2226
lines changed

19 files changed

+1209
-2226
lines changed

app/_components/FeatureComponents/PWA/PWAInstallPrompt.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useCallback, useEffect, useState } from "react";
3+
import { useCallback, useEffect, useState, type JSX } from "react";
44

55
type BeforeInstallPromptEvent = Event & {
66
prompt: () => Promise<void>;

app/_components/FeatureComponents/PWA/ServiceWorkerRegister.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ export const ServiceWorkerRegister = (): null => {
1313
r.scope.endsWith("/")
1414
);
1515
if (alreadyRegistered) return;
16-
await navigator.serviceWorker.register("/sw.js", { scope: "/" });
16+
await navigator.serviceWorker.register("/serwist/sw.js", {
17+
scope: "/",
18+
updateViaCache: "none",
19+
});
1720
} catch (_err) {}
1821
};
1922
register();

app/api/cronjobs/[id]/execute/route.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import { executeJob } from "@/app/_server/actions/cronjobs";
44

55
export const dynamic = "force-dynamic";
66

7-
export async function GET(
8-
request: NextRequest,
9-
{ params }: { params: { id: string } }
10-
) {
7+
export async function GET(request: NextRequest, props: { params: Promise<{ id: string }> }) {
8+
const params = await props.params;
119
const authError = await requireAuth(request);
1210
if (authError) return authError;
1311

app/api/cronjobs/[id]/route.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ import {
88

99
export const dynamic = "force-dynamic";
1010

11-
export async function GET(
12-
request: NextRequest,
13-
{ params }: { params: { id: string } }
14-
) {
11+
export async function GET(request: NextRequest, props: { params: Promise<{ id: string }> }) {
12+
const params = await props.params;
1513
const authError = await requireAuth(request);
1614
if (authError) return authError;
1715

@@ -40,10 +38,8 @@ export async function GET(
4038
}
4139
}
4240

43-
export async function PATCH(
44-
request: NextRequest,
45-
{ params }: { params: { id: string } }
46-
) {
41+
export async function PATCH(request: NextRequest, props: { params: Promise<{ id: string }> }) {
42+
const params = await props.params;
4743
const authError = await requireAuth(request);
4844
if (authError) return authError;
4945

@@ -79,10 +75,8 @@ export async function PATCH(
7975
}
8076
}
8177

82-
export async function DELETE(
83-
request: NextRequest,
84-
{ params }: { params: { id: string } }
85-
) {
78+
export async function DELETE(request: NextRequest, props: { params: Promise<{ id: string }> }) {
79+
const params = await props.params;
8680
const authError = await requireAuth(request);
8781
if (authError) return authError;
8882

app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const metadata: Metadata = {
3333
icons: {
3434
icon: "/favicon.png",
3535
shortcut: "/logo.png",
36-
apple: "/logo.png",
36+
apple: "/logo-pwa.png",
3737
},
3838
};
3939

app/serwist/[path]/route.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { createSerwistRoute } from "@serwist/turbopack";
2+
3+
const { GET } = createSerwistRoute({
4+
swSrc: "app/sw.ts",
5+
});
6+
7+
export { GET };

app/sw.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import type { PrecacheEntry, SerwistGlobalConfig } from "serwist";
2+
import {
3+
Serwist,
4+
NetworkFirst,
5+
CacheableResponsePlugin,
6+
ExpirationPlugin,
7+
StaleWhileRevalidate,
8+
CacheFirst,
9+
} from "serwist";
10+
import { cleanupOutdatedCaches } from "serwist/internal";
11+
12+
declare global {
13+
interface WorkerGlobalScope extends SerwistGlobalConfig {
14+
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined;
15+
}
16+
}
17+
18+
declare const self: WorkerGlobalScope;
19+
20+
const pageStrategy = new NetworkFirst({
21+
cacheName: "pages",
22+
matchOptions: { ignoreVary: true },
23+
networkTimeoutSeconds: 5,
24+
plugins: [
25+
new CacheableResponsePlugin({ statuses: [200] }),
26+
new ExpirationPlugin({
27+
maxEntries: 128,
28+
maxAgeSeconds: 30 * 24 * 60 * 60,
29+
}),
30+
],
31+
});
32+
33+
cleanupOutdatedCaches();
34+
35+
const serwist = new Serwist({
36+
precacheEntries: self.__SW_MANIFEST,
37+
skipWaiting: true,
38+
clientsClaim: true,
39+
navigationPreload: false,
40+
runtimeCaching: [
41+
{
42+
matcher: ({ request }) => request.mode === "navigate",
43+
handler: pageStrategy,
44+
},
45+
{
46+
matcher: ({ request, sameOrigin }) =>
47+
request.headers.get("RSC") === "1" && sameOrigin,
48+
handler: pageStrategy,
49+
},
50+
{
51+
matcher: /\/_next\/static.+\.js$/i,
52+
handler: new CacheFirst({
53+
cacheName: "static-js",
54+
plugins: [
55+
new ExpirationPlugin({
56+
maxEntries: 64,
57+
maxAgeSeconds: 30 * 24 * 60 * 60,
58+
}),
59+
],
60+
}),
61+
},
62+
{
63+
matcher: /\.(?:css|woff|woff2|ttf|eot|otf)$/i,
64+
handler: new StaleWhileRevalidate({
65+
cacheName: "static-assets",
66+
plugins: [
67+
new ExpirationPlugin({
68+
maxEntries: 64,
69+
maxAgeSeconds: 30 * 24 * 60 * 60,
70+
}),
71+
],
72+
}),
73+
},
74+
{
75+
matcher: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,
76+
handler: new StaleWhileRevalidate({
77+
cacheName: "images",
78+
plugins: [
79+
new ExpirationPlugin({
80+
maxEntries: 128,
81+
maxAgeSeconds: 30 * 24 * 60 * 60,
82+
}),
83+
],
84+
}),
85+
},
86+
],
87+
});
88+
89+
serwist.addEventListeners();

eslint.config.mjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import nextCoreWebVitals from "eslint-config-next/core-web-vitals";
2+
import nextTypescript from "eslint-config-next/typescript";
3+
4+
const eslintConfig = [
5+
...nextCoreWebVitals,
6+
...nextTypescript,
7+
{
8+
ignores: [
9+
"node_modules/**",
10+
".next/**",
11+
"out/**",
12+
"build/**",
13+
"next-env.d.ts",
14+
],
15+
},
16+
];
17+
18+
export default eslintConfig;

next-env.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/// <reference types="next" />
22
/// <reference types="next/image-types/global" />
3+
import "./.next/dev/types/routes.d.ts";
34

45
// NOTE: This file should not be edited
5-
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
6+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

next.config.js

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)