Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit 4e418e8

Browse files
committed
breaking: combine params and query of RouterURL
1 parent 1c64712 commit 4e418e8

File tree

7 files changed

+37
-35
lines changed

7 files changed

+37
-35
lines changed

framework/core/routing.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export class Routing {
131131
let locale = this._defaultLocale
132132
let pathname = decodeURI(url.pathname)
133133
let pagePath = ''
134-
let params: Record<string, string> = {}
134+
let params = new URLSearchParams()
135135
let nestedModules: RouteModule[] = []
136136

137137
if (pathname !== '/' && this._locales.length > 0) {
@@ -153,19 +153,25 @@ export class Routing {
153153
nestedModules.push(c.module)
154154
}
155155
pagePath = path
156-
params = p
156+
Object.entries(p).forEach(([key, value]) => {
157+
params.append(key, value)
158+
})
157159
return false
158160
}
159161
}, true)
160162

163+
for (const name of url.searchParams.keys()) {
164+
const values = url.searchParams.getAll(name)
165+
values.forEach(value => params.append(name, value))
166+
}
167+
161168
return [
162169
{
163170
baseURL: this._baseURL,
164171
locale,
165172
pathname,
166173
pagePath,
167174
params,
168-
query: url.searchParams,
169175
push: (url: string) => redirect(url),
170176
replace: (url: string) => redirect(url, true),
171177
},
@@ -238,8 +244,7 @@ export function createBlankRouterURL(baseURL = '/', locale = 'en'): RouterURL {
238244
locale,
239245
pagePath: '',
240246
pathname: '/',
241-
params: {},
242-
query: new URLSearchParams(),
247+
params: new URLSearchParams(),
243248
push: () => void 0,
244249
replace: () => void 0,
245250
}

framework/core/routing_test.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,47 +131,53 @@ Deno.test(`routing`, () => {
131131
const [router, nestedModules] = routing.createRouter({ pathname: '/blog/hello-world' })
132132
assertEquals(router.pathname, '/blog/hello-world')
133133
assertEquals(router.pagePath, '/blog/[slug]')
134-
assertEquals(router.params, { slug: 'hello-world' })
134+
assertEquals(router.params.get('slug'), 'hello-world')
135135
assertEquals(nestedModules.map(m => m.url), ['/pages/blog.tsx', '/pages/blog/[slug].tsx'])
136136
}
137137

138138
{
139139
const [router, nestedModules] = routing.createRouter({ pathname: '/user' })
140140
assertEquals(router.pathname, '/user')
141141
assertEquals(router.pagePath, '/user')
142-
assertEquals(router.params, {})
142+
assertEquals(nestedModules.map(m => m.url), ['/pages/user.tsx', '/pages/user/index.tsx'])
143+
}
144+
145+
{
146+
const [router, nestedModules] = routing.createRouter({ pathname: '/user?name=aleph' })
147+
assertEquals(router.pathname, '/user')
148+
assertEquals(router.pagePath, '/user')
149+
assertEquals(router.params.get('name'), 'aleph')
143150
assertEquals(nestedModules.map(m => m.url), ['/pages/user.tsx', '/pages/user/index.tsx'])
144151
}
145152

146153
{
147154
const [router, nestedModules] = routing.createRouter({ pathname: '/user/projects' })
148155
assertEquals(router.pathname, '/user/projects')
149156
assertEquals(router.pagePath, '/user/[...all]')
150-
assertEquals(router.params, { all: 'projects' })
157+
assertEquals(router.params.get('all'), 'projects')
151158
assertEquals(nestedModules.map(m => m.url), ['/pages/user.tsx', '/pages/user/[...all].tsx'])
152159
}
153160

154161
{
155162
const [router, nestedModules] = routing.createRouter({ pathname: '/user/settings/profile' })
156163
assertEquals(router.pathname, '/user/settings/profile')
157164
assertEquals(router.pagePath, '/user/[...all]')
158-
assertEquals(router.params, { all: 'settings/profile' })
165+
assertEquals(router.params.get('all'), 'settings/profile')
159166
assertEquals(nestedModules.map(m => m.url), ['/pages/user.tsx', '/pages/user/[...all].tsx'])
160167
}
161168

162169
{
163170
const [router, nestedModules] = routing.createRouter({ pathname: '/user/settings/security' })
164171
assertEquals(router.pathname, '/user/settings/security')
165172
assertEquals(router.pagePath, '/user/[...all]')
166-
assertEquals(router.params, { all: 'settings/security' })
173+
assertEquals(router.params.get('all'), 'settings/security')
167174
assertEquals(nestedModules.map(m => m.url), ['/pages/user.tsx', '/pages/user/[...all].tsx'])
168175
}
169176

170177
{
171178
const [router, nestedModules] = routing.createRouter({ pathname: '/null' })
172179
assertEquals(router.pathname, '/null')
173180
assertEquals(router.pagePath, '')
174-
assertEquals(router.params, {})
175181
assertEquals(nestedModules.map(m => m.url), [])
176182
}
177183
})

server/api.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import type { APIRequest, ServerRequest, ServerResponse } from '../types.ts'
88

99
export class Request implements APIRequest {
1010
#req: ServerRequest
11-
#params: Record<string, string>
12-
#query: URLSearchParams
11+
#params: URLSearchParams
1312
#cookies: ReadonlyMap<string, string>
1413
#resp = {
1514
status: 200,
@@ -19,10 +18,9 @@ export class Request implements APIRequest {
1918
done: false
2019
}
2120

22-
constructor(req: ServerRequest, params: Record<string, string>, query: URLSearchParams) {
21+
constructor(req: ServerRequest, params: URLSearchParams) {
2322
this.#req = req
2423
this.#params = params
25-
this.#query = query
2624
const cookies = new Map()
2725
this.headers.get('cookie')?.split(';').forEach(cookie => {
2826
const p = cookie.trim().split('=')
@@ -65,14 +63,10 @@ export class Request implements APIRequest {
6563
return this.#req.respond(r)
6664
}
6765

68-
get params(): Record<string, string> {
66+
get params(): URLSearchParams {
6967
return this.#params
7068
}
7169

72-
get query(): URLSearchParams {
73-
return this.#query
74-
}
75-
7670
get cookies(): ReadonlyMap<string, string> {
7771
return this.#cookies
7872
}

server/app.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ export class Application implements ServerApplication {
473473
return null
474474
}
475475

476-
const cacheKey = router.pathname + router.query.toString()
476+
const cacheKey = loc.pathname + (loc.search || '')
477477
const [_, data] = await this.#renderer.useCache(pagePath, cacheKey, async () => {
478478
return await this.#renderer.renderPage(router, nestedModules)
479479
})
@@ -485,7 +485,7 @@ export class Application implements ServerApplication {
485485
const [router, nestedModules] = this.#pageRouting.createRouter(loc)
486486
const { pagePath } = router
487487
const status = pagePath !== '' ? 200 : 404
488-
const path = router.pathname + router.query.toString()
488+
const path = loc.pathname + (loc.search || '')
489489

490490
if (!this.isSSRable(loc.pathname)) {
491491
const [html] = await this.#renderer.useCache('-', 'spa-index', async () => {

server/localproxy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export async function localProxy(cwd: string, port: number) {
1717
log.debug(`Proxy https://deno.land/x/aleph on http://localhost:${port}`)
1818
for await (const r of s) {
1919
const url = new URL('http://localhost' + r.url)
20-
const resp = new Request(r, {}, url.searchParams)
20+
const resp = new Request(r, url.searchParams)
2121
const filepath = join(cwd, url.pathname)
2222
try {
2323
const info = await Deno.lstat(filepath)

server/server.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class Server {
3131
const { baseUrl, rewrites } = app.config
3232
const url = rewriteURL(r.url, baseUrl, rewrites)
3333
const pathname = decodeURI(url.pathname)
34-
const req = new Request(r, {}, url.searchParams)
34+
const req = new Request(r, url.searchParams)
3535

3636
// set custom headers
3737
for (const key in app.config.headers) {
@@ -152,10 +152,10 @@ export class Server {
152152
const route = app.getAPIRoute({ pathname, search: url.searchParams.toString() })
153153
if (route !== null) {
154154
try {
155-
const [{ params, query }, { jsFile, hash }] = route
155+
const [{ params }, { jsFile, hash }] = route
156156
const { default: handle } = await import(`file://${jsFile}#${hash.slice(0, 6)}`)
157157
if (util.isFunction(handle)) {
158-
await handle(new Request(req, params, query))
158+
await handle(new Request(req, params))
159159
} else {
160160
req.status(500).json({ status: 500, message: 'bad api handler' })
161161
}

types.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ export interface ServerApplication {
102102
readonly mode: 'development' | 'production'
103103
readonly config: Required<Config>
104104
addModule(url: string, options?: { code?: string }): Promise<void>
105-
injectCode(stage: 'compilation' | 'hmr' | 'ssr', transform: TransformFn): void
106-
}
107-
108-
export type TransformFn = {
109-
(url: string, code: string): string
105+
injectCode(
106+
stage: 'compilation' | 'hmr' | 'ssr',
107+
transform: (url: string, code: string) => string
108+
): void
110109
}
111110

112111
/**
@@ -136,8 +135,7 @@ export interface ServerResponse {
136135
* An interface extends the `ServerRequest` for API requests.
137136
*/
138137
export interface APIRequest extends ServerRequest {
139-
readonly params: Record<string, string>
140-
readonly query: URLSearchParams
138+
readonly params: URLSearchParams
141139
readonly cookies: ReadonlyMap<string, string>
142140
/** `readBody` reads the body to an object in bytes, string, json, or multipart form data. */
143141
readBody(type?: 'raw'): Promise<Uint8Array>
@@ -181,8 +179,7 @@ export type RouterURL = {
181179
readonly locale: string
182180
readonly pathname: string
183181
readonly pagePath: string
184-
readonly params: Record<string, string>
185-
readonly query: URLSearchParams
182+
readonly params: URLSearchParams
186183
push(url: string): void
187184
replace(url: string): void
188185
}

0 commit comments

Comments
 (0)