From a90b488dcfdf3e82ee7e4c9057c9caf6261f4d81 Mon Sep 17 00:00:00 2001 From: Julien Oculi Date: Mon, 9 Dec 2024 14:28:33 +0100 Subject: [PATCH] refactor!: switch to fresh@2 --- README.md | 2 +- components/Header.tsx | 2 +- components/Markdown.tsx | 6 ++-- components/SponsorCards.tsx | 2 +- deno.json | 34 ++++++++++++++-------- dev.ts | 19 ++++++------ islands/IsOnline.tsx | 2 +- islands/ThemePicker.tsx | 2 +- main.ts | 39 ++++++++++++++++++------- routes/_404.tsx | 18 ------------ routes/_app.tsx | 13 +++++---- routes/_error.tsx | 40 ++++++++++++++++++++++++++ routes/_middleware.ts | 8 ++++-- routes/api/_middleware.ts | 8 ++++-- routes/api/magiclink/index.ts | 15 ++++++---- routes/api/serviceworker/is-online.tsx | 10 +++---- routes/api/webpush/vapid.ts | 7 +++-- routes/blog/[name].tsx | 6 ++-- routes/carnet/[id].tsx | 6 ++-- routes/imports/markdown_css.ts | 6 ++-- routes/index.tsx | 11 ++++--- routes/machines/[id].tsx | 6 ++-- routes/membres/[id]/index.tsx | 6 ++-- routes/projets/[id].tsx | 6 ++-- src/cache/middleware.ts | 4 +-- src/csp/middleware.ts | 2 +- src/security_headers/middleware.ts | 2 +- src/serviceworker/middleware.ts | 2 +- src/session/middleware.ts | 2 +- src/session/mod.ts | 4 +-- src/utils.ts | 4 +-- utils.ts | 8 ++++++ 32 files changed, 188 insertions(+), 114 deletions(-) delete mode 100644 routes/_404.tsx create mode 100644 routes/_error.tsx create mode 100644 utils.ts diff --git a/README.md b/README.md index bd8a819..7b5511b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ TODO echo 'cohabit.localhost' >> /etc/hosts # In sudo, one time mkcert -install # If mkcert is not installed in your root ca mkcert -ecdsa localhost # Only once to issue localhost certificates -deno task start +deno task dev ``` ### Production run diff --git a/components/Header.tsx b/components/Header.tsx index fa4b612..ad9e5a3 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,4 +1,4 @@ -import { asset } from '$fresh/runtime.ts' +import { asset } from 'fresh/runtime' import AiChatBox from ':islands/AiChatBox.tsx' import MoreBox from ':islands/MoreBox.tsx' import SearchBox from ':islands/SearchBox.tsx' diff --git a/components/Markdown.tsx b/components/Markdown.tsx index 0375ac4..9a0771d 100644 --- a/components/Markdown.tsx +++ b/components/Markdown.tsx @@ -1,11 +1,11 @@ -import { SignalLike } from '$fresh/src/types.ts' +import type { Signal } from '@preact/signals' import { render, RenderOptions } from '@deno/gfm' export type MarkdownTheme = 'light' | 'dark' | 'auto' export function Markdown( { children, theme, options }: { - children?: SignalLike | string - theme?: SignalLike | MarkdownTheme + children?: Signal | string + theme?: Signal | MarkdownTheme options?: RenderOptions }, ) { diff --git a/components/SponsorCards.tsx b/components/SponsorCards.tsx index 7ffb3ff..844eb94 100644 --- a/components/SponsorCards.tsx +++ b/components/SponsorCards.tsx @@ -1,4 +1,4 @@ -import { asset } from '$fresh/runtime.ts' +import { asset } from 'fresh/runtime' import { Picture } from ':components/Picture.tsx' export function SponsorCards() { diff --git a/deno.json b/deno.json index 62d9ab6..50b4159 100644 --- a/deno.json +++ b/deno.json @@ -2,13 +2,10 @@ "lock": false, "tasks": { "check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx", - "cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -", - "manifest": "deno task cli manifest $(pwd)", - "start": "deno run -A --watch=static/,routes/ dev.ts", + "dev": "deno run -A --watch=static/,routes/ dev.ts", "build": "deno run -A dev.ts build", - "preview": "deno run -A main.ts", - "update": "deno run -A -r https://fresh.deno.dev/update .", - "serve": "deno task preview", + "start": "deno run -A main.ts", + "update": "deno run -A -r jsr:@fresh/update .", "dev:add_package": "deno run --allow-net=git.cohabit.fr --allow-read=. --allow-write=./deno.json,./packages --allow-run=git,deno ./scripts/add_package.ts" }, "fmt": { @@ -29,7 +26,7 @@ "packages/" ], "imports": { - "$fresh/": "https://deno.land/x/fresh@1.6.8/", + "fresh": "jsr:@fresh/core@^2.0.0-alpha.25", "$std/": "https://deno.land/std@0.208.0/", ":components/": "./components/", ":islands/": "./islands/", @@ -40,8 +37,7 @@ "@deno/gfm": "https://deno.land/x/gfm@0.6.0/mod.ts", "@jotsr/delayed": "jsr:@jotsr/delayed@^2.1.1", "@jotsr/smart-css-bundler": "jsr:@jotsr/smart-css-bundler@^0.3.0", - "@preact/signals": "https://esm.sh/*@preact/signals@^1.2.3", - "@preact/signals-core": "npm:@preact/signals-core@^1.6.1", + "@preact/signals": "npm:@preact/signals@^1.3.0", "@simplewebauthn/browser": "npm:@simplewebauthn/browser@^10.0.0", "@simplewebauthn/server": "npm:@simplewebauthn/server@^10.0.0", "@simplewebauthn/types": "npm:@simplewebauthn/types@^10.0.0", @@ -51,13 +47,27 @@ "@std/json": "jsr:@std/json@^0.224.1", "@std/streams": "jsr:@std/streams@^0.224.5", "@univoq/": "https://deno.land/x/univoq@0.2.0/", - "preact": "npm:preact@10.22.0", + "preact": "npm:preact@^10.24.2", "univoq": "https://deno.land/x/univoq@0.2.0/mod.ts", "web-push": "npm:web-push@^3.6.7" }, "compilerOptions": { - "jsx": "react-jsx", - "jsxImportSource": "preact" + "lib": [ + "dom", + "dom.asynciterable", + "dom.iterable", + "deno.ns" + ], + "jsx": "precompile", + "jsxImportSource": "preact", + "jsxPrecompileSkipElements": [ + "a", + "img", + "source", + "body", + "html", + "head" + ] }, "unstable": [ "kv" diff --git a/dev.ts b/dev.ts index 20efcb8..9e9499d 100644 --- a/dev.ts +++ b/dev.ts @@ -1,14 +1,15 @@ #!/usr/bin/env -S deno run -A --watch=static/,routes/ -import dev from '$fresh/dev.ts' -import config from './fresh.config.ts' - -import '$std/dotenv/load.ts' +import { Builder } from 'fresh/dev' +import { app } from './main.ts' +const builder = new Builder() const hostname = 'cohabit.localhost' -await dev(import.meta.url, './main.ts', { - ...config, - server: { + +if (Deno.args.includes('build')) { + await builder.build(app) +} else { + await builder.listen(app, { cert: await Deno.readTextFile('./cert/cohabit.localhost.pem'), key: await Deno.readTextFile('./cert/cohabit.localhost-key.pem'), hostname, @@ -20,5 +21,5 @@ await dev(import.meta.url, './main.ts', { 'color: blue; text-decoration: underline', ) }), - }, -}) + }) +} diff --git a/islands/IsOnline.tsx b/islands/IsOnline.tsx index e5dbfc2..6713993 100644 --- a/islands/IsOnline.tsx +++ b/islands/IsOnline.tsx @@ -1,6 +1,6 @@ import { type Signal, useComputed, useSignal } from '@preact/signals' import { useEffect } from 'preact/hooks' -import { IS_BROWSER } from '$fresh/runtime.ts' +import { IS_BROWSER } from 'fresh/runtime' type NetworkConnection = { addEventListener: ( diff --git a/islands/ThemePicker.tsx b/islands/ThemePicker.tsx index 9f7e167..9bdcd38 100644 --- a/islands/ThemePicker.tsx +++ b/islands/ThemePicker.tsx @@ -1,5 +1,5 @@ import { useComputed, useSignal, useSignalEffect } from '@preact/signals' -import { IS_BROWSER } from '$fresh/runtime.ts' +import { IS_BROWSER } from 'fresh/runtime' export default function ThemePicker() { const colorSchemeQuery = '(prefers-color-scheme: dark)' diff --git a/main.ts b/main.ts index 13d2f71..715e08d 100644 --- a/main.ts +++ b/main.ts @@ -1,13 +1,32 @@ -/// -/// -/// -/// -/// +import { App, fsRoutes, staticFiles } from 'fresh' +import { type State } from './utils.ts' +import { contentType } from 'jsr:@std/media-types@1/content-type' -import '$std/dotenv/load.ts' +export const app = new App() +app.use(staticFiles()) -import { start } from '$fresh/server.ts' -import manifest from './fresh.gen.ts' -import config from './fresh.config.ts' +// temp fix before updating cssBundler middleware +app.use(async (ctx) => { + const response = await ctx.next() + if (response.status === 404) { + const ext = ctx.url.pathname.split('.').at(-1) ?? '.bin' + const mime = contentType(ext) ?? 'application/octet-stream' + const file = await Deno.readFile(`./_fresh/static/${ctx.url.pathname}`) + return new Response(file, { + headers: { + 'Content-Type': mime, + }, + }) + } + return response +}) -await start(manifest, config) +await fsRoutes(app, { + dir: './', + loadIsland: (path) => import(`./islands/${path}`), + loadRoute: (path) => import(`./routes/${path}`), +}) + +if (import.meta.main) { + await app.listen() +} diff --git a/routes/_404.tsx b/routes/_404.tsx deleted file mode 100644 index d51d295..0000000 --- a/routes/_404.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Head } from '$fresh/runtime.ts' - -export default function Error404() { - return ( - <> - - Page non trouvée - -
-

Erreur 404 - Page non trouvé

-

- La page que vous recherché n'existe pas ou a été supprimée. -

- Retourner à l'accueil -
- - ) -} diff --git a/routes/_app.tsx b/routes/_app.tsx index 0fe5565..0c91411 100644 --- a/routes/_app.tsx +++ b/routes/_app.tsx @@ -1,14 +1,16 @@ -import { asset, Head, Partial } from '$fresh/runtime.ts' -import { type PageProps } from '$fresh/server.ts' +import { asset, Partial } from 'fresh/runtime' +import { type PageProps } from 'fresh' import { Footer } from ':components/Footer.tsx' import { Header } from ':components/Header.tsx' import { ProgressiveWebApp } from ':components/ProgressiveWebApp.tsx' import IsOnline from ':islands/IsOnline.tsx' -export default function App({ Component }: PageProps) { +export default function App( + { Component, data }: PageProps<{ title?: string } | undefined>, +) { return ( - + - + {data?.title ?? 'Fablab Coh@bit'} +
+

Uknown server error

+ + ) + } + + const status = ctx.error.status + + if (status === 404) { + return ( + <> +
+

Erreur 404 - Page non trouvé

+

+ La page que vous recherché n'existe pas ou a été supprimée. +

+ Retourner à l'accueil +
+ + ) + } + + return ( +
+

Uknown http error

+
+ ) +}) diff --git a/routes/_middleware.ts b/routes/_middleware.ts index cfa4bcd..9f3c335 100644 --- a/routes/_middleware.ts +++ b/routes/_middleware.ts @@ -1,12 +1,14 @@ -import { FreshContext } from '$fresh/server.ts' import { useCache } from ':src/cache/middleware.ts' import { useCsp } from ':src/csp/middleware.ts' import { useSecurityHeaders } from ':src/security_headers/middleware.ts' import { useServiceworker } from ':src/serviceworker/middleware.ts' import { useSession } from ':src/session/middleware.ts' import { SessionStore } from ':src/session/mod.ts' +import { define } from '../utils.ts' + +export default define.middleware(async (ctx) => { + const request = ctx.req -export async function handler(request: Request, ctx: FreshContext) { // Update fresh context state with session ctx.state = { ...ctx.state, session: SessionStore.getFromRequest(request) } @@ -25,4 +27,4 @@ export async function handler(request: Request, ctx: FreshContext) { useCache(request, response, ctx) return response -} +}) diff --git a/routes/api/_middleware.ts b/routes/api/_middleware.ts index 2774698..91e6d8f 100644 --- a/routes/api/_middleware.ts +++ b/routes/api/_middleware.ts @@ -1,9 +1,11 @@ -import { FreshContext } from '$fresh/server.ts' import { SessionStore } from ':src/session/mod.ts' import { respondApi } from ':src/utils.ts' +import { define } from '../../utils.ts' -export function handler(request: Request, ctx: FreshContext) { +export const handler = define.handlers((ctx) => { // Check CSRF token + const request = ctx.req + if (['POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'].includes(request.method)) { const session = SessionStore.getFromRequest(request) const csrf = session?.get('_csrf') @@ -14,4 +16,4 @@ export function handler(request: Request, ctx: FreshContext) { } return ctx.next() -} +}) diff --git a/routes/api/magiclink/index.ts b/routes/api/magiclink/index.ts index b205cde..9f332e3 100644 --- a/routes/api/magiclink/index.ts +++ b/routes/api/magiclink/index.ts @@ -1,7 +1,8 @@ import 'npm:iterator-polyfill' +import { define } from '../../../utils.ts' // Polyfill AsyncIterator -import { FreshContext } from '$fresh/server.ts' +import { FreshContext } from 'fresh' import { db } from ':src/db/mod.ts' import { SessionHandlers, SessionStore } from ':src/session/mod.ts' import { respondApi } from ':src/utils.ts' @@ -24,9 +25,11 @@ export async function getUserByMail(email: string): Promise { return user } - -export const handler: SessionHandlers = { - async POST(request, ctx) { +*/ +export const handler = define.handlers({}) +/* + async POST(ctx) { + const request = ctx.req const { email } = await request.json() as { email: string } // check email before continue @@ -118,8 +121,8 @@ export const handler: SessionHandlers = { 401, ) }, -} - +}) +/* function remoteId( { headers }: { headers: Headers }, { remoteAddr }: { remoteAddr: FreshContext['remoteAddr'] }, diff --git a/routes/api/serviceworker/is-online.tsx b/routes/api/serviceworker/is-online.tsx index 1772bb6..54c21cf 100644 --- a/routes/api/serviceworker/is-online.tsx +++ b/routes/api/serviceworker/is-online.tsx @@ -1,9 +1,9 @@ -import { SessionHandlers } from ':src/session/mod.ts' +import { define } from '../../../utils.ts' -export const handler: SessionHandlers = { - GET(req: Request, ctx) { - const { response } = Deno.upgradeWebSocket(req) +export const handler = define.handlers({ + GET(ctx) { + const { response } = Deno.upgradeWebSocket(ctx.req) ctx.state.skipMiddlewares = true return response }, -} +}) diff --git a/routes/api/webpush/vapid.ts b/routes/api/webpush/vapid.ts index 62f8471..1c08c16 100644 --- a/routes/api/webpush/vapid.ts +++ b/routes/api/webpush/vapid.ts @@ -1,9 +1,10 @@ -import { Handlers } from '$fresh/server.ts' import { respondApi } from ':src/utils.ts' import { publicKey } from ':src/webpush/mod.ts' +import { define } from '../../../utils.ts' -export const handler: Handlers = { +export const handler = define.handlers({ GET() { + console.log('VAPID', publicKey) return respondApi('success', publicKey) }, -} +}) diff --git a/routes/blog/[name].tsx b/routes/blog/[name].tsx index 4dc64bc..a68bc29 100644 --- a/routes/blog/[name].tsx +++ b/routes/blog/[name].tsx @@ -1,8 +1,8 @@ -import { RouteContext } from '$fresh/server.ts' +import { define } from '../../utils.ts' import { BlogPost } from ':components/BlogBlocks.tsx' import { fetchNews } from ':src/blog/mod.ts' -export default async function Blog(_req: Request, { params }: RouteContext) { +export default define.page(async ({ params }) => { try { const article = await fetchNews('cohabit', params.name) return BlogPost(article) @@ -14,4 +14,4 @@ export default async function Blog(_req: Request, { params }: RouteContext) { ) } -} +}) diff --git a/routes/carnet/[id].tsx b/routes/carnet/[id].tsx index 2f1b27d..cfc2f76 100644 --- a/routes/carnet/[id].tsx +++ b/routes/carnet/[id].tsx @@ -1,9 +1,9 @@ -import { PageProps } from '$fresh/server.ts' import { Markdown } from ':components/Markdown.tsx' import { db } from ':src/db/mod.ts' import { fetchCarnet } from ':src/members/mod.ts' +import { define } from '../../utils.ts' -export default async function Member(_: Request, { params }: PageProps) { +export default define.page(async ({ params }) => { const uuid = params.id as ReturnType const user = await db.resource.user.get({ uuid }).catch(() => undefined) @@ -24,4 +24,4 @@ export default async function Member(_: Request, { params }: PageProps) { {carnet} ) -} +}) diff --git a/routes/imports/markdown_css.ts b/routes/imports/markdown_css.ts index 6e7af77..b483a29 100644 --- a/routes/imports/markdown_css.ts +++ b/routes/imports/markdown_css.ts @@ -1,7 +1,7 @@ -import { Handlers } from '$fresh/server.ts' import { CSS, KATEX_CSS } from '@deno/gfm' +import { define } from '../../utils.ts' -export const handler: Handlers = { +export const handler = define.handlers({ GET() { const styles = CSS + KATEX_CSS return new Response(styles, { @@ -11,4 +11,4 @@ export const handler: Handlers = { }, }) }, -} +}) diff --git a/routes/index.tsx b/routes/index.tsx index 5645c53..c4c65ca 100644 --- a/routes/index.tsx +++ b/routes/index.tsx @@ -1,4 +1,3 @@ -import { Head } from '$fresh/runtime.ts' import { AutoGrid } from ':components/AutoGrid.tsx' import { CohabitInfoTable } from ':components/CohabitInfoTable.tsx' import { Heros } from ':components/Heros.tsx' @@ -7,13 +6,17 @@ import { ProjectCard, projectMock } from ':components/ProjectCard.tsx' import { SponsorCards } from ':components/SponsorCards.tsx' import BlogCardList from ':islands/BlogCardList.tsx' import MemberCardList from ':islands/MemberCardList.tsx' +import { define } from '../utils.ts' + +export const handler = define.handlers({ + GET() { + return { data: { title: 'Fablab Coh@bit' } } + }, +}) export default function Home() { return ( <> - - Fablab Coh@bit -

Nos actus

diff --git a/routes/machines/[id].tsx b/routes/machines/[id].tsx index c62b41d..ff05e5b 100644 --- a/routes/machines/[id].tsx +++ b/routes/machines/[id].tsx @@ -1,10 +1,10 @@ -import { PageProps } from '$fresh/server.ts' +import { define } from '../../utils.ts' import { MachineCard, machineMock } from ':components/MachineCard.tsx' -export default function Machine({ params }: PageProps) { +export default define.page(({ params }) => { const machine = machineMock.at(Number(params.id)) return ( machine ? MachineCard(machine) :

Machine pas encore disponible

) -} +}) diff --git a/routes/membres/[id]/index.tsx b/routes/membres/[id]/index.tsx index 4ab9c33..97174c7 100644 --- a/routes/membres/[id]/index.tsx +++ b/routes/membres/[id]/index.tsx @@ -1,10 +1,10 @@ -import { PageProps } from '$fresh/server.ts' import { Markdown } from ':components/Markdown.tsx' import { MemberCard } from ':components/MemberCard.tsx' import { db } from ':src/db/mod.ts' import { fetchProfile, userToMemberCardProps } from ':src/members/mod.ts' +import { define } from '../../../utils.ts' -export default async function Member(_: Request, { params, url }: PageProps) { +export default define.page(async ({ params, url }) => { const uuid = params.id as ReturnType const user = await db.resource.user.get({ uuid }).catch(() => undefined) @@ -56,4 +56,4 @@ export default async function Member(_: Request, { params, url }: PageProps) { ) -} +}) diff --git a/routes/projets/[id].tsx b/routes/projets/[id].tsx index a232cdd..00bc27b 100644 --- a/routes/projets/[id].tsx +++ b/routes/projets/[id].tsx @@ -1,7 +1,7 @@ -import { PageProps } from '$fresh/server.ts' import { ProjectCard, projectMock } from ':components/ProjectCard.tsx' +import { define } from '../../utils.ts' -export default function Projets({ params }: PageProps) { +export default define.page(({ params }) => { const Projets = projectMock.at(Number(params.id)) return ( @@ -9,4 +9,4 @@ export default function Projets({ params }: PageProps) { ? ProjectCard(Projets) :

Projets inconnu, peut être un futur

) -} +}) diff --git a/src/cache/middleware.ts b/src/cache/middleware.ts index aa94667..f52fcee 100644 --- a/src/cache/middleware.ts +++ b/src/cache/middleware.ts @@ -1,11 +1,11 @@ -import { FreshContext } from '$fresh/server.ts' +import { FreshContext } from 'fresh' export function useCache( _request: Request, response: Response, ctx: FreshContext, ) { - if (ctx.config.dev) return + if (ctx.config.mode === 'development') return if ( ctx.url.pathname.match( /(.+\.|_)((css)|(ttf)|(woff2)|(png)|(svg)|(jpe?g)|(avif))/, diff --git a/src/csp/middleware.ts b/src/csp/middleware.ts index 9eab075..d08bf54 100644 --- a/src/csp/middleware.ts +++ b/src/csp/middleware.ts @@ -1,4 +1,4 @@ -import { FreshContext } from '$fresh/server.ts' +import { FreshContext } from 'fresh' import { applyCspRulesWithNonce, CspRules } from ':src/csp/mod.ts' export function useCsp( diff --git a/src/security_headers/middleware.ts b/src/security_headers/middleware.ts index d90a6da..c3c7bd2 100644 --- a/src/security_headers/middleware.ts +++ b/src/security_headers/middleware.ts @@ -1,4 +1,4 @@ -import { FreshContext } from '$fresh/server.ts' +import { FreshContext } from 'fresh' export function useSecurityHeaders( _request: Request, diff --git a/src/serviceworker/middleware.ts b/src/serviceworker/middleware.ts index 9f60d00..8c05fef 100644 --- a/src/serviceworker/middleware.ts +++ b/src/serviceworker/middleware.ts @@ -1,4 +1,4 @@ -import { FreshContext } from '$fresh/server.ts' +import { FreshContext } from 'fresh' export function useServiceworker( _request: Request, diff --git a/src/session/middleware.ts b/src/session/middleware.ts index e979d1a..6078439 100644 --- a/src/session/middleware.ts +++ b/src/session/middleware.ts @@ -1,4 +1,4 @@ -import { FreshContext } from '$fresh/server.ts' +import { FreshContext } from 'fresh' import { SessionStore } from ':src/session/mod.ts' import { getCookies, setCookie } from 'jsr:@std/http@^0.224.4/cookie' diff --git a/src/session/mod.ts b/src/session/mod.ts index 861bb79..2f36bfe 100644 --- a/src/session/mod.ts +++ b/src/session/mod.ts @@ -1,4 +1,4 @@ -import type { Handlers, PageProps } from '$fresh/server.ts' +import type { PageProps, RouteHandler } from 'fresh' import { getCookies } from '@std/http/cookie' type SessionEntry = { @@ -15,7 +15,7 @@ export type SessionPageProps> = PageProps export type SessionHandlers> = - Handlers + RouteHandler export class SessionStore { static #store = new Map() diff --git a/src/utils.ts b/src/utils.ts index f35dbc1..63ea524 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { SignalLike } from '$fresh/src/types.ts' +import type { Signal } from '@preact/signals' import { JsonValue } from '$std/json/common.ts' import { decodeBase64 } from '@std/encoding/base64' import { JsonStringifyStream } from '@std/json' @@ -173,7 +173,7 @@ export function base64ToString(base64: string): string { return new TextDecoder().decode(bytes) } -export function unwrapSignalOrValue(valueOrSignal: T | SignalLike): T { +export function unwrapSignalOrValue(valueOrSignal: T | Signal): T { if (typeof valueOrSignal !== 'object') { return valueOrSignal } diff --git a/utils.ts b/utils.ts new file mode 100644 index 0000000..dcc66a0 --- /dev/null +++ b/utils.ts @@ -0,0 +1,8 @@ +import { createDefine } from 'fresh' + +// deno-lint-ignore no-empty-interface +export interface State { + skipMiddlewares?: true +} + +export const define = createDefine()