From 0b5165735da07845b07deadfe7e1672e6b111c3f Mon Sep 17 00:00:00 2001 From: James Anderson Date: Thu, 3 Oct 2024 20:56:16 +0100 Subject: [PATCH] chore: restructure and change exports (#8) --- .eslintrc | 2 +- fixtures/check-route-match/config.ts | 4 +- fixtures/check-route-match/file-system.ts | 3 +- fixtures/dynamic-routes/config.ts | 4 +- fixtures/dynamic-routes/file-system.ts | 3 +- fixtures/i18n/config.ts | 4 +- fixtures/i18n/file-system.ts | 3 +- fixtures/infinite-loop/config.ts | 4 +- fixtures/infinite-loop/file-system.ts | 3 +- fixtures/run-test-set.ts | 39 ++++++++++++------- fixtures/trailing-slash/config.ts | 4 +- fixtures/trailing-slash/file-system.ts | 3 +- package.json | 33 ++++------------ .../images/format-resizing-response.spec.ts | 3 +- .../images/format-resizing-response.ts | 4 +- .../images/get-resizing-properties.spec.ts | 3 +- .../images/get-resizing-properties.ts | 10 ++--- src/{utils => }/images/index.ts | 1 + .../images/is-remote-pattern-match.spec.ts | 3 +- .../images/is-remote-pattern-match.ts | 2 +- .../images/index.ts => images/types.ts} | 10 ++--- src/index.ts | 3 +- .../http/apply-headers.spec.ts | 3 +- src/{utils => router}/http/apply-headers.ts | 4 +- .../http/apply-search-params.spec.ts | 0 .../http/apply-search-params.ts | 0 .../http/create-mutable-response.ts | 0 .../http/create-route-request.spec.ts | 0 .../http/create-route-request.ts | 0 src/{utils => router}/http/index.ts | 0 src/{utils => router}/http/is-url.spec.ts | 0 src/{utils => router}/http/is-url.ts | 0 .../http/parse-accept-language.spec.ts | 0 .../http/parse-accept-language.ts | 0 src/router/index.ts | 5 +++ .../pcre/apply-pcre-matches.spec.ts | 3 +- .../pcre/apply-pcre-matches.ts | 0 src/{utils => router}/pcre/index.ts | 0 src/{utils => router}/pcre/match-pcre.spec.ts | 3 +- src/{utils => router}/pcre/match-pcre.ts | 0 .../index.ts => router/request-context.ts} | 10 ++--- src/{ => router}/router.ts | 6 +-- src/{ => router}/routes-matcher.ts | 16 ++++---- .../build-output/route.ts => router/types.ts} | 21 ++++++++-- .../utils}/check-has-field.spec.ts | 3 +- .../utils}/check-has-field.ts | 4 +- .../utils}/collect-locales-from-routes.ts | 3 +- .../utils}/get-next-phase.ts | 2 +- .../utils}/group-routes-by-phase.ts | 3 +- src/{utils/routing => router/utils}/index.ts | 0 .../utils}/is-handler-route.ts | 2 +- .../utils}/is-locale-trailing-slash-regex.ts | 0 src/types/build-output/function.ts | 7 ---- src/types/build-output/index.ts | 2 - src/types/utilities/index.ts | 3 -- src/types/vercel-config/index.ts | 19 --------- 56 files changed, 118 insertions(+), 149 deletions(-) rename src/{utils => }/images/format-resizing-response.spec.ts (97%) rename src/{utils => }/images/format-resizing-response.ts (92%) rename src/{utils => }/images/get-resizing-properties.spec.ts (99%) rename src/{utils => }/images/get-resizing-properties.ts (88%) rename src/{utils => }/images/index.ts (83%) rename src/{utils => }/images/is-remote-pattern-match.spec.ts (97%) rename src/{utils => }/images/is-remote-pattern-match.ts (94%) rename src/{types/images/index.ts => images/types.ts} (85%) rename src/{utils => router}/http/apply-headers.spec.ts (96%) rename src/{utils => router}/http/apply-headers.ts (90%) rename src/{utils => router}/http/apply-search-params.spec.ts (100%) rename src/{utils => router}/http/apply-search-params.ts (100%) rename src/{utils => router}/http/create-mutable-response.ts (100%) rename src/{utils => router}/http/create-route-request.spec.ts (100%) rename src/{utils => router}/http/create-route-request.ts (100%) rename src/{utils => router}/http/index.ts (100%) rename src/{utils => router}/http/is-url.spec.ts (100%) rename src/{utils => router}/http/is-url.ts (100%) rename src/{utils => router}/http/parse-accept-language.spec.ts (100%) rename src/{utils => router}/http/parse-accept-language.ts (100%) create mode 100644 src/router/index.ts rename src/{utils => router}/pcre/apply-pcre-matches.spec.ts (98%) rename src/{utils => router}/pcre/apply-pcre-matches.ts (100%) rename src/{utils => router}/pcre/index.ts (100%) rename src/{utils => router}/pcre/match-pcre.spec.ts (96%) rename src/{utils => router}/pcre/match-pcre.ts (100%) rename src/{types/request-context/index.ts => router/request-context.ts} (61%) rename src/{ => router}/router.ts (94%) rename src/{ => router}/routes-matcher.ts (98%) rename src/{types/build-output/route.ts => router/types.ts} (74%) rename src/{utils/routing => router/utils}/check-has-field.spec.ts (98%) rename src/{utils/routing => router/utils}/check-has-field.ts (94%) rename src/{utils/routing => router/utils}/collect-locales-from-routes.ts (88%) rename src/{utils/routing => router/utils}/get-next-phase.ts (94%) rename src/{utils/routing => router/utils}/group-routes-by-phase.ts (98%) rename src/{utils/routing => router/utils}/index.ts (100%) rename src/{utils/routing => router/utils}/is-handler-route.ts (78%) rename src/{utils/routing => router/utils}/is-locale-trailing-slash-regex.ts (100%) delete mode 100644 src/types/build-output/function.ts delete mode 100644 src/types/build-output/index.ts delete mode 100644 src/types/utilities/index.ts delete mode 100644 src/types/vercel-config/index.ts diff --git a/.eslintrc b/.eslintrc index d36f995..cba006c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,7 +11,7 @@ "import/no-extraneous-dependencies": [ "error", - { "devDependencies": ["**/*.spec.ts", "vite.config.ts"] }, + { "devDependencies": ["**/*.spec.ts", "vite.config.ts", "fixtures/**/*.ts"] }, ], "import/extensions": ["error", "never"], "no-console": "error", diff --git a/fixtures/check-route-match/config.ts b/fixtures/check-route-match/config.ts index 3b9b757..5b61562 100644 --- a/fixtures/check-route-match/config.ts +++ b/fixtures/check-route-match/config.ts @@ -1,6 +1,6 @@ -import type { VercelConfig } from '@/types/vercel-config'; +import type { Config } from '@/router'; -export const config: VercelConfig = { +export const config: Config = { version: 3, routes: [ { src: '^/valid-src-only$', dest: '/' }, diff --git a/fixtures/check-route-match/file-system.ts b/fixtures/check-route-match/file-system.ts index cd1b795..e314339 100644 --- a/fixtures/check-route-match/file-system.ts +++ b/fixtures/check-route-match/file-system.ts @@ -1,5 +1,4 @@ -import type { BuildOutput } from '@/types/build-output'; - +import type { BuildOutput } from '../run-test-set'; import { functionAsset, htmlAsset } from '../run-test-set'; export const fileSystem: BuildOutput = { diff --git a/fixtures/dynamic-routes/config.ts b/fixtures/dynamic-routes/config.ts index 3b8cd00..10d590b 100644 --- a/fixtures/dynamic-routes/config.ts +++ b/fixtures/dynamic-routes/config.ts @@ -1,6 +1,6 @@ -import type { VercelConfig } from '@/types/vercel-config'; +import type { Config } from '@/router'; -export const config: VercelConfig = { +export const config: Config = { version: 3, routes: [ { diff --git a/fixtures/dynamic-routes/file-system.ts b/fixtures/dynamic-routes/file-system.ts index 5f746e9..7463545 100644 --- a/fixtures/dynamic-routes/file-system.ts +++ b/fixtures/dynamic-routes/file-system.ts @@ -1,5 +1,4 @@ -import type { BuildOutput } from '@/types/build-output'; - +import type { BuildOutput } from '../run-test-set'; import { functionAsset, htmlAsset, staticAsset } from '../run-test-set'; export const fileSystem: BuildOutput = { diff --git a/fixtures/i18n/config.ts b/fixtures/i18n/config.ts index 5466b69..004876b 100644 --- a/fixtures/i18n/config.ts +++ b/fixtures/i18n/config.ts @@ -1,6 +1,6 @@ -import type { VercelConfig } from '@/types/vercel-config'; +import type { Config } from '@/router'; -export const config: VercelConfig = { +export const config: Config = { version: 3, routes: [ { diff --git a/fixtures/i18n/file-system.ts b/fixtures/i18n/file-system.ts index a91b41b..f5cd9eb 100644 --- a/fixtures/i18n/file-system.ts +++ b/fixtures/i18n/file-system.ts @@ -1,5 +1,4 @@ -import type { BuildOutput } from '@/types/build-output'; - +import type { BuildOutput } from '../run-test-set'; import { functionAsset, htmlAsset, staticAsset } from '../run-test-set'; export const staticLocales = ['en', 'fr', 'nl', 'es'] as const; diff --git a/fixtures/infinite-loop/config.ts b/fixtures/infinite-loop/config.ts index 4493aaf..a6b2ef4 100644 --- a/fixtures/infinite-loop/config.ts +++ b/fixtures/infinite-loop/config.ts @@ -1,6 +1,6 @@ -import type { VercelConfig } from '@/types/vercel-config'; +import type { Config } from '@/router'; -export const config: VercelConfig = { +export const config: Config = { version: 3, routes: [ { src: '^/invalid$', dest: '/invalid/new', status: 404 }, diff --git a/fixtures/infinite-loop/file-system.ts b/fixtures/infinite-loop/file-system.ts index b798006..3bc7001 100644 --- a/fixtures/infinite-loop/file-system.ts +++ b/fixtures/infinite-loop/file-system.ts @@ -1,5 +1,4 @@ -import type { BuildOutput } from '@/types/build-output'; - +import type { BuildOutput } from '../run-test-set'; import { functionAsset, htmlAsset } from '../run-test-set'; export const fileSystem: BuildOutput = { diff --git a/fixtures/run-test-set.ts b/fixtures/run-test-set.ts index 33f85a1..d97a89a 100644 --- a/fixtures/run-test-set.ts +++ b/fixtures/run-test-set.ts @@ -1,17 +1,29 @@ import { readFileSync } from 'node:fs'; import { join } from 'node:path'; -// eslint-disable-next-line import/no-extraneous-dependencies import { expect, suite, test, vi } from 'vitest'; -import type { BuildOutputItem, EdgeFunction, ExecutionContext } from '@/types/build-output'; -import type { Assets, Fetcher } from '@/types/request-context'; -import type { VercelConfig } from '@/types/vercel-config'; -import { applyHeaders, applySearchParams, createRouteRequest } from '@/utils/http'; -import { collectLocalesFromRoutes, groupRoutesByPhase } from '@/utils/routing'; +import type { Config } from '@/router'; +import { applyHeaders, applySearchParams, createRouteRequest } from '@/router/http'; +import { collectLocalesFromRoutes, groupRoutesByPhase } from '@/router/utils'; +import type { RequestContext } from '../src'; import { Router } from '../src'; +export type BuildOutputItem = + | { type: 'function' | 'middleware'; entrypoint: string } + | { type: 'static'; path?: string; headers?: Record }; + +export type BuildOutput = Record; + +type Fetcher = { + fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise; +}; + +type EdgeFunction = { + default: (request: Request, context: RequestContext['ctx']) => Response | Promise; +}; + type TestCase = { name: string; paths: string[]; @@ -64,7 +76,7 @@ export const functionAsset = (path: string) => export const runTestSet = (ctx: { name: string; desc: string; - config: VercelConfig; + config: Config; fileSystem: Record; cases: TestCase[]; }) => { @@ -77,9 +89,7 @@ export const runTestSet = (ctx: { const outputDir = join(__dirname, ctx.name, 'output'); - const executionContext: ExecutionContext = { - waitUntil: () => null, - }; + const executionCtx: RequestContext['ctx'] = { waitUntil: () => null }; const assetsFetcher: Fetcher = { fetch: (input: RequestInfo | URL) => { @@ -108,7 +118,7 @@ export const runTestSet = (ctx: { const request = new Request(url, { method, headers }); const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => null); - const assets: Assets = { + const assets: RequestContext['assets'] = { has: (p) => p in ctx.fileSystem, get: (p) => { const entry = ctx.fileSystem[p]; @@ -116,6 +126,9 @@ export const runTestSet = (ctx: { return { kind: entry.type, + isStaticAsset: entry.type === 'static', + isMiddleware: entry.type === 'middleware', + isRouteFunction: entry.type === 'function', fetch: async ({ path, searchParams }) => { let resp: Response | undefined; @@ -129,7 +142,7 @@ export const runTestSet = (ctx: { const edgeFuncJs = readFileSync(join(outputDir, entry.entrypoint)).toString(); // eslint-disable-next-line no-eval const edgeFunction: EdgeFunction = eval(edgeFuncJs.toString()); - resp = await edgeFunction.default(req, executionContext); + resp = await edgeFunction.default(req, executionCtx); break; } case 'static': { @@ -151,7 +164,7 @@ export const runTestSet = (ctx: { }, }; - const res = await router.fetch({ request, assets, ctx: executionContext }); + const res = await router.fetch({ request, assets, ctx: executionCtx }); expect(res.status).toEqual(expected.status); const textContent = await res.text(); diff --git a/fixtures/trailing-slash/config.ts b/fixtures/trailing-slash/config.ts index 2e79d7d..4a3c517 100644 --- a/fixtures/trailing-slash/config.ts +++ b/fixtures/trailing-slash/config.ts @@ -1,6 +1,6 @@ -import type { VercelConfig } from '@/types/vercel-config'; +import type { Config } from '@/router'; -export const config: VercelConfig = { +export const config: Config = { version: 3, routes: [ { diff --git a/fixtures/trailing-slash/file-system.ts b/fixtures/trailing-slash/file-system.ts index bdbbd8d..e950d89 100644 --- a/fixtures/trailing-slash/file-system.ts +++ b/fixtures/trailing-slash/file-system.ts @@ -1,5 +1,4 @@ -import type { BuildOutput } from '@/types/build-output'; - +import type { BuildOutput } from '../run-test-set'; import { functionAsset, htmlAsset, staticAsset } from '../run-test-set'; export const fileSystem: BuildOutput = { diff --git a/package.json b/package.json index 6a889e0..23b4c1b 100644 --- a/package.json +++ b/package.json @@ -11,32 +11,15 @@ "require": "./dist/index.cjs", "types": "./dist/index.d.ts" }, - "./types/build-output": { - "types": "./dist/types/build-output/index.d.ts" + "./router": { + "import": "./dist/router/index.js", + "require": "./dist/router/index.cjs", + "types": "./dist/router/index.d.ts" }, - "./types/images": { - "types": "./dist/types/images/index.d.ts" - }, - "./types/request-context": { - "types": "./dist/types/request-context/index.d.ts" - }, - "./types/vercel-config": { - "types": "./dist/types/vercel-config/index.d.ts" - }, - "./utils/http": { - "import": "./dist/utils/http/index.js", - "require": "./dist/utils/http/index.cjs", - "types": "./dist/utils/http/index.d.ts" - }, - "./utils/images": { - "import": "./dist/utils/images/index.js", - "require": "./dist/utils/images/index.cjs", - "types": "./dist/utils/images/index.d.ts" - }, - "./utils/routing": { - "import": "./dist/utils/routing/index.js", - "require": "./dist/utils/routing/index.cjs", - "types": "./dist/utils/routing/index.d.ts" + "./images": { + "import": "./dist/images/index.js", + "require": "./dist/images/index.cjs", + "types": "./dist/images/index.d.ts" } }, "publishConfig": { diff --git a/src/utils/images/format-resizing-response.spec.ts b/src/images/format-resizing-response.spec.ts similarity index 97% rename from src/utils/images/format-resizing-response.spec.ts rename to src/images/format-resizing-response.spec.ts index c7ed951..fe17d35 100644 --- a/src/utils/images/format-resizing-response.spec.ts +++ b/src/images/format-resizing-response.spec.ts @@ -1,8 +1,7 @@ import { expect, suite, test } from 'vitest'; -import type { ImagesConfig } from '@/types/images'; - import { formatResizingResponse } from './format-resizing-response'; +import type { ImagesConfig } from './types'; const baseConfig: ImagesConfig = { domains: ['example.com'], diff --git a/src/utils/images/format-resizing-response.ts b/src/images/format-resizing-response.ts similarity index 92% rename from src/utils/images/format-resizing-response.ts rename to src/images/format-resizing-response.ts index 333558e..c49d2eb 100644 --- a/src/utils/images/format-resizing-response.ts +++ b/src/images/format-resizing-response.ts @@ -1,6 +1,6 @@ -import type { ImagesConfig } from '@/types/images'; +import { applyHeaders, createMutableResponse } from '@/router/http'; -import { applyHeaders, createMutableResponse } from '../http'; +import type { ImagesConfig } from './types'; /** * Formats the given response to match the images configuration spec from the build output diff --git a/src/utils/images/get-resizing-properties.spec.ts b/src/images/get-resizing-properties.spec.ts similarity index 99% rename from src/utils/images/get-resizing-properties.spec.ts rename to src/images/get-resizing-properties.spec.ts index 8ae8bf8..7366313 100644 --- a/src/utils/images/get-resizing-properties.spec.ts +++ b/src/images/get-resizing-properties.spec.ts @@ -1,8 +1,7 @@ import { expect, suite, test } from 'vitest'; -import type { ImagesConfig } from '@/types/images'; - import { getResizingProperties } from './get-resizing-properties'; +import type { ImagesConfig } from './types'; const baseUrl = 'https://localhost/_next/image?url='; const baseValidUrl = `${baseUrl}%2Fimages%2F1.jpg`; diff --git a/src/utils/images/get-resizing-properties.ts b/src/images/get-resizing-properties.ts similarity index 88% rename from src/utils/images/get-resizing-properties.ts rename to src/images/get-resizing-properties.ts index 2381bf9..f308cdf 100644 --- a/src/utils/images/get-resizing-properties.ts +++ b/src/images/get-resizing-properties.ts @@ -1,7 +1,5 @@ -import type { ImageFormatWithoutPrefix, ImagesConfig } from '@/types/images'; -import type { Maybe } from '@/types/utilities'; - import { isRemotePatternMatch } from './is-remote-pattern-match'; +import type { ImageFormatWithoutPrefix, ImagesConfig } from './types'; export type ResizingProperties = { isRelative: boolean; @@ -57,9 +55,9 @@ export const getResizingProperties = ( } const acceptHeader = request.headers.get('Accept') ?? ''; - const format = config?.formats - ?.find((f) => acceptHeader.includes(f)) - ?.replace('image/', '') as Maybe; + const format = config?.formats?.find((f) => acceptHeader.includes(f))?.replace('image/', '') as + | ImageFormatWithoutPrefix + | undefined; return { isRelative, diff --git a/src/utils/images/index.ts b/src/images/index.ts similarity index 83% rename from src/utils/images/index.ts rename to src/images/index.ts index c90c3f0..5cee98e 100644 --- a/src/utils/images/index.ts +++ b/src/images/index.ts @@ -1,3 +1,4 @@ export * from './format-resizing-response'; export * from './get-resizing-properties'; export * from './is-remote-pattern-match'; +export * from './types'; diff --git a/src/utils/images/is-remote-pattern-match.spec.ts b/src/images/is-remote-pattern-match.spec.ts similarity index 97% rename from src/utils/images/is-remote-pattern-match.spec.ts rename to src/images/is-remote-pattern-match.spec.ts index 7b8c741..7c7aa38 100644 --- a/src/utils/images/is-remote-pattern-match.spec.ts +++ b/src/images/is-remote-pattern-match.spec.ts @@ -1,8 +1,7 @@ import { expect, suite, test } from 'vitest'; -import type { RemotePattern } from '@/types/images'; - import { isRemotePatternMatch } from './is-remote-pattern-match'; +import type { RemotePattern } from './types'; suite('isRemotePatternMatch', () => { test('hostname matches correctly', () => { diff --git a/src/utils/images/is-remote-pattern-match.ts b/src/images/is-remote-pattern-match.ts similarity index 94% rename from src/utils/images/is-remote-pattern-match.ts rename to src/images/is-remote-pattern-match.ts index 48c67e5..28e0c61 100644 --- a/src/utils/images/is-remote-pattern-match.ts +++ b/src/images/is-remote-pattern-match.ts @@ -1,4 +1,4 @@ -import type { RemotePattern } from '@/types/images'; +import type { RemotePattern } from './types'; /** * Checks whether the given URL matches the given remote pattern from the build output images diff --git a/src/types/images/index.ts b/src/images/types.ts similarity index 85% rename from src/types/images/index.ts rename to src/images/types.ts index 5392ea0..84b4331 100644 --- a/src/types/images/index.ts +++ b/src/images/types.ts @@ -1,8 +1,3 @@ -import type { StripPrefix } from '@/types/utilities'; - -export type ImageFormat = 'image/avif' | 'image/webp'; -export type ImageFormatWithoutPrefix = StripPrefix; - export type RemotePattern = { protocol?: 'http' | 'https'; hostname: string; @@ -10,6 +5,11 @@ export type RemotePattern = { pathname?: string; }; +type StripPrefix = T extends `${K}${infer V}` ? V : T; + +export type ImageFormat = 'image/avif' | 'image/webp'; +export type ImageFormatWithoutPrefix = StripPrefix; + export type ImagesConfig = { sizes: number[]; domains: string[]; diff --git a/src/index.ts b/src/index.ts index 164ab50..b7702a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ -export * from './router'; +export type { Assets, RequestContext } from './router'; +export { Router } from './router'; diff --git a/src/utils/http/apply-headers.spec.ts b/src/router/http/apply-headers.spec.ts similarity index 96% rename from src/utils/http/apply-headers.spec.ts rename to src/router/http/apply-headers.spec.ts index a9dc9aa..e571113 100644 --- a/src/utils/http/apply-headers.spec.ts +++ b/src/router/http/apply-headers.spec.ts @@ -1,7 +1,6 @@ import { expect, suite, test } from 'vitest'; -import type { MatchPCREResult } from '@/utils/pcre'; - +import type { MatchPCREResult } from '../pcre'; import { applyHeaders } from './apply-headers'; suite('applyHeaders', () => { diff --git a/src/utils/http/apply-headers.ts b/src/router/http/apply-headers.ts similarity index 90% rename from src/utils/http/apply-headers.ts rename to src/router/http/apply-headers.ts index 80a1371..f50795d 100644 --- a/src/utils/http/apply-headers.ts +++ b/src/router/http/apply-headers.ts @@ -1,5 +1,5 @@ -import type { MatchPCREResult } from '@/utils/pcre'; -import { applyPCREMatches } from '@/utils/pcre'; +import type { MatchPCREResult } from '../pcre'; +import { applyPCREMatches } from '../pcre'; /** * Applies a set of headers to a response. diff --git a/src/utils/http/apply-search-params.spec.ts b/src/router/http/apply-search-params.spec.ts similarity index 100% rename from src/utils/http/apply-search-params.spec.ts rename to src/router/http/apply-search-params.spec.ts diff --git a/src/utils/http/apply-search-params.ts b/src/router/http/apply-search-params.ts similarity index 100% rename from src/utils/http/apply-search-params.ts rename to src/router/http/apply-search-params.ts diff --git a/src/utils/http/create-mutable-response.ts b/src/router/http/create-mutable-response.ts similarity index 100% rename from src/utils/http/create-mutable-response.ts rename to src/router/http/create-mutable-response.ts diff --git a/src/utils/http/create-route-request.spec.ts b/src/router/http/create-route-request.spec.ts similarity index 100% rename from src/utils/http/create-route-request.spec.ts rename to src/router/http/create-route-request.spec.ts diff --git a/src/utils/http/create-route-request.ts b/src/router/http/create-route-request.ts similarity index 100% rename from src/utils/http/create-route-request.ts rename to src/router/http/create-route-request.ts diff --git a/src/utils/http/index.ts b/src/router/http/index.ts similarity index 100% rename from src/utils/http/index.ts rename to src/router/http/index.ts diff --git a/src/utils/http/is-url.spec.ts b/src/router/http/is-url.spec.ts similarity index 100% rename from src/utils/http/is-url.spec.ts rename to src/router/http/is-url.spec.ts diff --git a/src/utils/http/is-url.ts b/src/router/http/is-url.ts similarity index 100% rename from src/utils/http/is-url.ts rename to src/router/http/is-url.ts diff --git a/src/utils/http/parse-accept-language.spec.ts b/src/router/http/parse-accept-language.spec.ts similarity index 100% rename from src/utils/http/parse-accept-language.spec.ts rename to src/router/http/parse-accept-language.spec.ts diff --git a/src/utils/http/parse-accept-language.ts b/src/router/http/parse-accept-language.ts similarity index 100% rename from src/utils/http/parse-accept-language.ts rename to src/router/http/parse-accept-language.ts diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..5fd7c4d --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,5 @@ +export { applyHeaders, applySearchParams } from './http'; +export * from './request-context'; +export * from './router'; +export * from './types'; +export { collectLocalesFromRoutes, groupRoutesByPhase } from './utils'; diff --git a/src/utils/pcre/apply-pcre-matches.spec.ts b/src/router/pcre/apply-pcre-matches.spec.ts similarity index 98% rename from src/utils/pcre/apply-pcre-matches.spec.ts rename to src/router/pcre/apply-pcre-matches.spec.ts index 36cb186..d4f706b 100644 --- a/src/utils/pcre/apply-pcre-matches.spec.ts +++ b/src/router/pcre/apply-pcre-matches.spec.ts @@ -1,7 +1,6 @@ import { expect, suite, test } from 'vitest'; -import type { SourceRoute } from '@/types/build-output'; - +import type { SourceRoute } from '../types'; import { applyPCREMatches } from './apply-pcre-matches'; import { matchPCRE } from './match-pcre'; diff --git a/src/utils/pcre/apply-pcre-matches.ts b/src/router/pcre/apply-pcre-matches.ts similarity index 100% rename from src/utils/pcre/apply-pcre-matches.ts rename to src/router/pcre/apply-pcre-matches.ts diff --git a/src/utils/pcre/index.ts b/src/router/pcre/index.ts similarity index 100% rename from src/utils/pcre/index.ts rename to src/router/pcre/index.ts diff --git a/src/utils/pcre/match-pcre.spec.ts b/src/router/pcre/match-pcre.spec.ts similarity index 96% rename from src/utils/pcre/match-pcre.spec.ts rename to src/router/pcre/match-pcre.spec.ts index 576020a..c4a3476 100644 --- a/src/utils/pcre/match-pcre.spec.ts +++ b/src/router/pcre/match-pcre.spec.ts @@ -1,7 +1,6 @@ import { expect, suite, test } from 'vitest'; -import type { SourceRoute } from '@/types/build-output'; - +import type { SourceRoute } from '../types'; import { matchPCRE } from './match-pcre'; type TestCase = { diff --git a/src/utils/pcre/match-pcre.ts b/src/router/pcre/match-pcre.ts similarity index 100% rename from src/utils/pcre/match-pcre.ts rename to src/router/pcre/match-pcre.ts diff --git a/src/types/request-context/index.ts b/src/router/request-context.ts similarity index 61% rename from src/types/request-context/index.ts rename to src/router/request-context.ts index 58fc3e9..d92b92b 100644 --- a/src/types/request-context/index.ts +++ b/src/router/request-context.ts @@ -1,15 +1,15 @@ -import type { ExecutionContext } from '@/types/build-output'; - export type Assets = { has: (path: string) => boolean; get: (path: string) => { - kind: 'static' | 'middleware' | 'function'; + isStaticAsset: boolean; + isMiddleware: boolean; + isRouteFunction: boolean; fetch: (data: { path: string; searchParams: URLSearchParams }) => Promise; } | null; }; -export type Fetcher = { - fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise; +type ExecutionContext = { + waitUntil: (promise: Promise) => void; }; export type RequestContext = { diff --git a/src/router.ts b/src/router/router.ts similarity index 94% rename from src/router.ts rename to src/router/router.ts index 73d0970..f128836 100644 --- a/src/router.ts +++ b/src/router/router.ts @@ -1,9 +1,9 @@ -import type { RoutesGroupedByPhase } from '@/types/build-output'; -import type { RequestContext } from '@/types/request-context'; -import { applyHeaders, applySearchParams, isUrl } from '@/utils/http'; +import { applyHeaders, applySearchParams, isUrl } from '@/router/http'; +import type { RequestContext } from './request-context'; import type { ConfigMetadata, RoutingMatch } from './routes-matcher'; import { RoutesMatcher } from './routes-matcher'; +import type { RoutesGroupedByPhase } from './types'; export class Router { constructor( diff --git a/src/routes-matcher.ts b/src/router/routes-matcher.ts similarity index 98% rename from src/routes-matcher.ts rename to src/router/routes-matcher.ts index fa63b88..c8d4708 100644 --- a/src/routes-matcher.ts +++ b/src/router/routes-matcher.ts @@ -1,12 +1,12 @@ import { parse } from 'cookie'; -import type { Phase, RoutesGroupedByPhase, SourceRoute } from '@/types/build-output'; -import type { RequestContext } from '@/types/request-context'; -import type { WildCard } from '@/types/vercel-config'; -import { applyHeaders, applySearchParams, isUrl, parseAcceptLanguage } from '@/utils/http'; -import type { MatchPCREResult } from '@/utils/pcre'; -import { applyPCREMatches, matchPCRE } from '@/utils/pcre'; -import { checkHasField, getNextPhase, isLocaleTrailingSlashRegex } from '@/utils/routing'; +import { applyHeaders, applySearchParams, isUrl, parseAcceptLanguage } from '@/router/http'; +import type { MatchPCREResult } from '@/router/pcre'; +import { applyPCREMatches, matchPCRE } from '@/router/pcre'; +import { checkHasField, getNextPhase, isLocaleTrailingSlashRegex } from '@/router/utils'; + +import type { RequestContext } from './request-context'; +import type { Phase, RoutesGroupedByPhase, SourceRoute, WildCard } from './types'; export type ConfigMetadata = { locales: Set; @@ -254,7 +254,7 @@ export class RoutesMatcher { if (!path) return true; const item = path && this.ctx.assets.get(path); - if (!item || item.kind !== 'middleware') { + if (!item || !item.isMiddleware) { // The middleware function could not be found. Set the status to 500 and bail out. this.status = 500; return false; diff --git a/src/types/build-output/route.ts b/src/router/types.ts similarity index 74% rename from src/types/build-output/route.ts rename to src/router/types.ts index 00a49b0..fa01605 100644 --- a/src/types/build-output/route.ts +++ b/src/router/types.ts @@ -1,3 +1,5 @@ +import type { ImagesConfig } from '@/images'; + export type Phase = | 'none' // represents source routes that are not under a handler | 'rewrite' @@ -47,8 +49,19 @@ export type Route = SourceRoute | HandlerRoute; export type RoutesGroupedByPhase = Record; -export type BuildOutputItem = - | { type: 'function' | 'middleware'; entrypoint: string } - | { type: 'static'; path?: string; headers?: Record }; +export type WildCard = { domain: string; value: string }; + +type Override = { path?: string; contentType?: string }; -export type BuildOutput = Record; +type Cron = { path: string; schedule: string }; + +export type Config = { + version: 3; + routes?: Route[]; + images?: ImagesConfig; + wildcard?: WildCard[]; + overrides?: Record; + framework?: { version: string }; + cache?: string[]; + crons?: Cron[]; +}; diff --git a/src/utils/routing/check-has-field.spec.ts b/src/router/utils/check-has-field.spec.ts similarity index 98% rename from src/utils/routing/check-has-field.spec.ts rename to src/router/utils/check-has-field.spec.ts index 69b143b..3f92efe 100644 --- a/src/utils/routing/check-has-field.spec.ts +++ b/src/router/utils/check-has-field.spec.ts @@ -1,8 +1,7 @@ import { parse } from 'cookie'; import { expect, suite, test } from 'vitest'; -import type { SourceRouteHasField } from '@/types/build-output'; - +import type { SourceRouteHasField } from '../types'; import { checkHasField } from './check-has-field'; type HasFieldTestCase = { diff --git a/src/utils/routing/check-has-field.ts b/src/router/utils/check-has-field.ts similarity index 94% rename from src/utils/routing/check-has-field.ts rename to src/router/utils/check-has-field.ts index 06fd816..2b261c9 100644 --- a/src/utils/routing/check-has-field.ts +++ b/src/router/utils/check-has-field.ts @@ -1,5 +1,5 @@ -import type { SourceRouteHasField } from '@/types/build-output'; -import { applyPCREMatches, matchPCRE } from '@/utils/pcre'; +import { applyPCREMatches, matchPCRE } from '../pcre'; +import type { SourceRouteHasField } from '../types'; /** * Gets the has field PCRE match results, and tries to apply any named capture groups to a diff --git a/src/utils/routing/collect-locales-from-routes.ts b/src/router/utils/collect-locales-from-routes.ts similarity index 88% rename from src/utils/routing/collect-locales-from-routes.ts rename to src/router/utils/collect-locales-from-routes.ts index edc19bd..28737d9 100644 --- a/src/utils/routing/collect-locales-from-routes.ts +++ b/src/router/utils/collect-locales-from-routes.ts @@ -1,5 +1,4 @@ -import type { Route, RoutesGroupedByPhase } from '@/types/build-output'; - +import type { Route, RoutesGroupedByPhase } from '../types'; import { isHandlerRoute } from './is-handler-route'; /** diff --git a/src/utils/routing/get-next-phase.ts b/src/router/utils/get-next-phase.ts similarity index 94% rename from src/utils/routing/get-next-phase.ts rename to src/router/utils/get-next-phase.ts index d46864e..d75eaf2 100644 --- a/src/utils/routing/get-next-phase.ts +++ b/src/router/utils/get-next-phase.ts @@ -1,4 +1,4 @@ -import type { Phase } from '@/types/build-output'; +import type { Phase } from '../types'; /** * Gets the next phase of the routing process. diff --git a/src/utils/routing/group-routes-by-phase.ts b/src/router/utils/group-routes-by-phase.ts similarity index 98% rename from src/utils/routing/group-routes-by-phase.ts rename to src/router/utils/group-routes-by-phase.ts index b58fa76..dcd4089 100644 --- a/src/utils/routing/group-routes-by-phase.ts +++ b/src/router/utils/group-routes-by-phase.ts @@ -1,5 +1,4 @@ -import type { Phase, Route, RoutesGroupedByPhase, SourceRoute } from '@/types/build-output'; - +import type { Phase, Route, RoutesGroupedByPhase, SourceRoute } from '../types'; import { isHandlerRoute } from './is-handler-route'; const append = (str: string, suffix: string) => (str.endsWith(suffix) ? str : `${str}${suffix}`); diff --git a/src/utils/routing/index.ts b/src/router/utils/index.ts similarity index 100% rename from src/utils/routing/index.ts rename to src/router/utils/index.ts diff --git a/src/utils/routing/is-handler-route.ts b/src/router/utils/is-handler-route.ts similarity index 78% rename from src/utils/routing/is-handler-route.ts rename to src/router/utils/is-handler-route.ts index ae61617..e258fbd 100644 --- a/src/utils/routing/is-handler-route.ts +++ b/src/router/utils/is-handler-route.ts @@ -1,4 +1,4 @@ -import type { HandlerRoute, Route } from '@/types/build-output'; +import type { HandlerRoute, Route } from '../types'; /** * Determine whether a route is a source route or a handler. diff --git a/src/utils/routing/is-locale-trailing-slash-regex.ts b/src/router/utils/is-locale-trailing-slash-regex.ts similarity index 100% rename from src/utils/routing/is-locale-trailing-slash-regex.ts rename to src/router/utils/is-locale-trailing-slash-regex.ts diff --git a/src/types/build-output/function.ts b/src/types/build-output/function.ts deleted file mode 100644 index 8704166..0000000 --- a/src/types/build-output/function.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type ExecutionContext = { - waitUntil: (promise: Promise) => void; -}; - -export type EdgeFunction = { - default: (request: Request, context: ExecutionContext) => Response | Promise; -}; diff --git a/src/types/build-output/index.ts b/src/types/build-output/index.ts deleted file mode 100644 index b0c7e2d..0000000 --- a/src/types/build-output/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './function'; -export * from './route'; diff --git a/src/types/utilities/index.ts b/src/types/utilities/index.ts deleted file mode 100644 index 889e2ae..0000000 --- a/src/types/utilities/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type StripPrefix = T extends `${K}${infer V}` ? V : T; - -export type Maybe = T | undefined; diff --git a/src/types/vercel-config/index.ts b/src/types/vercel-config/index.ts deleted file mode 100644 index 1fbe52e..0000000 --- a/src/types/vercel-config/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Route } from '@/types/build-output'; -import type { ImagesConfig } from '@/types/images'; - -export type WildCard = { domain: string; value: string }; - -type Override = { path?: string; contentType?: string }; - -type Cron = { path: string; schedule: string }; - -export type VercelConfig = { - version: 3; - routes?: Route[]; - images?: ImagesConfig; - wildcard?: WildCard[]; - overrides?: Record; - framework?: { version: string }; - cache?: string[]; - crons?: Cron[]; -};