Skip to content

Commit addd528

Browse files
committed
feat: allow defining params on top level object when using makeUrl and makeSignedUrl methods
1 parent a4f6f3d commit addd528

File tree

5 files changed

+147
-19
lines changed

5 files changed

+147
-19
lines changed

adonis-typings/route.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,14 @@ declare module '@ioc:Adonis/Core/Route' {
203203
params?: any,
204204
domainParams?: any,
205205
prefixDomain?: boolean,
206+
} & { [key: string]: any }
207+
208+
/**
209+
* Options for making a signed url
210+
*/
211+
export type MakeSignedUrlOptions = MakeUrlOptions & {
212+
expiresIn?: string | number,
213+
purpose?: string,
206214
}
207215

208216
/**
@@ -244,7 +252,7 @@ declare module '@ioc:Adonis/Core/Route' {
244252

245253
makeSignedUrl (
246254
routeIdentifier: string,
247-
options?: MakeUrlOptions & { expiresIn?: string | number, purpose?: string },
255+
options?: MakeSignedUrlOptions,
248256
domain?: string,
249257
): string | null
250258

src/Router/index.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,26 @@ import { EncryptionContract } from '@ioc:Adonis/Core/Encryption'
1515

1616
import {
1717
RouteNode,
18+
RouteHandler,
1819
MatchedRoute,
1920
RouteMatchers,
2021
RouterContract,
2122
MakeUrlOptions,
2223
RouteLookupNode,
23-
RouteHandler,
24+
MakeSignedUrlOptions,
2425
} from '@ioc:Adonis/Core/Route'
2526

2627
import { Route } from './Route'
2728
import { Store } from './Store'
2829
import { RouteGroup } from './Group'
2930
import { BriskRoute } from './BriskRoute'
3031
import { RouteResource } from './Resource'
31-
import { toRoutesJSON, processPattern } from '../helpers'
32+
import {
33+
toRoutesJSON,
34+
processPattern,
35+
normalizeMakeUrlOptions,
36+
normalizeMakeSignedUrlOptions,
37+
} from '../helpers'
3238

3339
/**
3440
* Router class exposes unified API to create new routes, group them or
@@ -382,7 +388,7 @@ export class Router implements RouterContract {
382388
/**
383389
* Normalizing options
384390
*/
385-
options = Object.assign({ qs: {}, params: {}, domainParams: {}, prefixDomain: true }, options)
391+
options = normalizeMakeUrlOptions(options)
386392

387393
/**
388394
* Processing the route pattern with dynamic segments
@@ -408,15 +414,15 @@ export class Router implements RouterContract {
408414
*/
409415
public makeSignedUrl (
410416
routeIdentifier: string,
411-
options?: MakeUrlOptions & { expiresIn?: string | number, purpose?: string },
417+
options?: MakeSignedUrlOptions,
412418
domain?: string,
413419
): string | null {
414420
const route = this.lookup(routeIdentifier, domain)
415421
if (!route) {
416422
return null
417423
}
418424

419-
options = Object.assign({ qs: {}, params: {}, domainParams: {}, prefixDomain: true }, options)
425+
options = normalizeMakeSignedUrlOptions(options)
420426

421427
/**
422428
* Making the signature from the qualified url. We do not prefix the domain when

src/helpers.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { Route } from './Router/Route'
1616
import { RouteGroup } from './Router/Group'
1717
import { BriskRoute } from './Router/BriskRoute'
1818
import { RouteResource } from './Router/Resource'
19-
import { RouteJSON } from '@ioc:Adonis/Core/Route'
19+
import { RouteJSON, MakeUrlOptions, MakeSignedUrlOptions } from '@ioc:Adonis/Core/Route'
2020
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
2121

2222
const proxyCache = new QuickLru({ maxSize: 100 })
@@ -136,3 +136,39 @@ export function trustProxy (
136136
proxyCache.set(remoteAddress, result)
137137
return result
138138
}
139+
140+
/**
141+
* Normalizes the make url options by allowing params to appear on
142+
* top level object with option to nest inside `params` property.
143+
*/
144+
export function normalizeMakeUrlOptions (options?: MakeUrlOptions): Required<MakeUrlOptions> {
145+
const params = options ? (options.params ? options.params : options) : {}
146+
const qs = options && options.qs ? options.qs : {}
147+
const domainParams = options && options.domainParams ? options.domainParams : {}
148+
const prefixDomain = options && options.prefixDomain !== undefined ? options.prefixDomain : true
149+
return { params, qs, domainParams, prefixDomain }
150+
}
151+
152+
/**
153+
* Normalizes the make signed url options by allowing params to appear on
154+
* top level object with option to nest inside `params` property.
155+
*/
156+
export function normalizeMakeSignedUrlOptions (
157+
options?: MakeSignedUrlOptions,
158+
): Required<MakeUrlOptions> & { purpose?: string, expiresIn?: string | number } {
159+
const params = options ? (options.params ? options.params : options) : {}
160+
const qs = options && options.qs ? options.qs : {}
161+
const domainParams = options && options.domainParams ? options.domainParams : {}
162+
const prefixDomain = options && options.prefixDomain !== undefined ? options.prefixDomain : true
163+
const expiresIn = options && options.expiresIn !== undefined ? options.expiresIn : undefined
164+
const purpose = options && options.purpose ? options.purpose : undefined
165+
166+
return {
167+
params,
168+
qs,
169+
domainParams,
170+
prefixDomain,
171+
expiresIn,
172+
purpose,
173+
}
174+
}

test/helpers.spec.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* @adonisjs/http-server
3+
*
4+
* (c) Harminder Virk <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import test from 'japa'
11+
import { normalizeMakeUrlOptions, normalizeMakeSignedUrlOptions } from '../src/helpers'
12+
13+
test.group('Helpers | normalizeMakeUrlOptions', () => {
14+
test('use top level object as params', (assert) => {
15+
assert.deepEqual(normalizeMakeUrlOptions({ id: 1, qs: { method: '_GET' } }), {
16+
params: { id: 1, qs: { method: '_GET' } },
17+
qs: { method: '_GET' },
18+
domainParams: {},
19+
prefixDomain: true,
20+
})
21+
})
22+
23+
test('use top params as params when defined explictly', (assert) => {
24+
assert.deepEqual(normalizeMakeUrlOptions({ params: { id: 1 }, qs: { method: '_GET' } }), {
25+
params: { id: 1 },
26+
qs: { method: '_GET' },
27+
domainParams: {},
28+
prefixDomain: true,
29+
})
30+
})
31+
})
32+
33+
test.group('Helpers | normalizeMakeSignedUrlOptions', () => {
34+
test('use top level object as params', (assert) => {
35+
assert.deepEqual(normalizeMakeSignedUrlOptions({ id: 1, qs: { method: '_GET' } }), {
36+
params: { id: 1, qs: { method: '_GET' } },
37+
qs: { method: '_GET' },
38+
domainParams: {},
39+
prefixDomain: true,
40+
expiresIn: undefined,
41+
purpose: undefined,
42+
})
43+
})
44+
45+
test('use top params as params when defined explictly', (assert) => {
46+
assert.deepEqual(normalizeMakeSignedUrlOptions({ params: { id: 1 }, qs: { method: '_GET' } }), {
47+
params: { id: 1 },
48+
qs: { method: '_GET' },
49+
domainParams: {},
50+
prefixDomain: true,
51+
expiresIn: undefined,
52+
purpose: undefined,
53+
})
54+
})
55+
56+
test('return expiresIn value when defined', (assert) => {
57+
assert.deepEqual(normalizeMakeSignedUrlOptions({ id: 1, expiresIn: '1min' }), {
58+
params: { id: 1, expiresIn: '1min' },
59+
qs: {},
60+
domainParams: {},
61+
prefixDomain: true,
62+
expiresIn: '1min',
63+
purpose: undefined,
64+
})
65+
})
66+
67+
test('return purpose value when defined', (assert) => {
68+
assert.deepEqual(normalizeMakeSignedUrlOptions({ id: 1, purpose: 'login' }), {
69+
params: { id: 1, purpose: 'login' },
70+
qs: {},
71+
domainParams: {},
72+
prefixDomain: true,
73+
expiresIn: undefined,
74+
purpose: 'login',
75+
})
76+
})
77+
})
78+

test/router.spec.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,13 +2004,13 @@ test.group('Brisk route', () => {
20042004
})
20052005
})
20062006

2007-
test.group('Make url', () => {
2007+
test.group('Router | Make url', () => {
20082008
test('make url to a given route', (assert) => {
20092009
const router = new Router(encryption)
20102010
router.get('posts/:id', async function handler () {})
20112011
router.commit()
20122012

2013-
const url = router.makeUrl('/posts/:id', { params: { id: 1 } })!
2013+
const url = router.makeUrl('/posts/:id', { id: 1 })!
20142014
assert.equal(url, '/posts/1')
20152015
})
20162016

@@ -2019,7 +2019,7 @@ test.group('Make url', () => {
20192019
router.get('posts/:id', async function handler () {}).as('showPost')
20202020
router.commit()
20212021

2022-
const url = router.makeUrl('showPost', { params: { id: 1 } })!
2022+
const url = router.makeUrl('showPost', { id: 1 })!
20232023
assert.equal(url, '/posts/1')
20242024
})
20252025

@@ -2028,7 +2028,7 @@ test.group('Make url', () => {
20282028
router.get('posts/:id', 'PostsController.index').as('showPost')
20292029
router.commit()
20302030

2031-
const url = router.makeUrl('PostsController.index', { params: { id: 1 } })!
2031+
const url = router.makeUrl('PostsController.index', { id: 1 })!
20322032
assert.equal(url, '/posts/1')
20332033
})
20342034

@@ -2037,7 +2037,7 @@ test.group('Make url', () => {
20372037
router.get('posts/:id', 'PostsController.index').domain('blog.adonisjs.com')
20382038
router.commit()
20392039

2040-
const url = router.makeUrl('PostsController.index', { params: { id: 1 } })
2040+
const url = router.makeUrl('PostsController.index', { id: 1 })
20412041
assert.equal(url, '//blog.adonisjs.com/posts/1')
20422042
})
20432043
})
@@ -2048,7 +2048,7 @@ test.group('Make signed url', () => {
20482048
router.get('posts/:id', async function handler () {})
20492049
router.commit()
20502050

2051-
const url = router.makeSignedUrl('/posts/:id', { params: { id: 1 } })!
2051+
const url = router.makeSignedUrl('/posts/:id', { id: 1 })!
20522052
const qs = parse(url.split('?')[1])
20532053
assert.equal(encryption.verifier.unsign(qs.signature as string), '/posts/1')
20542054
})
@@ -2059,7 +2059,7 @@ test.group('Make signed url', () => {
20592059
router.get('posts/:id', async function handler () {}).as('showPost')
20602060
router.commit()
20612061

2062-
const url = router.makeSignedUrl('showPost', { params: { id: 1 } })!
2062+
const url = router.makeSignedUrl('showPost', { id: 1 })!
20632063
const qs = parse(url.split('?')[1])
20642064
assert.equal(encryption.verifier.unsign(qs.signature as string), '/posts/1')
20652065
})
@@ -2070,7 +2070,7 @@ test.group('Make signed url', () => {
20702070
router.get('posts/:id', 'PostsController.index').as('showPost')
20712071
router.commit()
20722072

2073-
const url = router.makeSignedUrl('PostsController.index', { params: { id: 1 } })!
2073+
const url = router.makeSignedUrl('PostsController.index', { id: 1 })!
20742074
const qs = parse(url.split('?')[1])
20752075
assert.equal(encryption.verifier.unsign(qs.signature as string), '/posts/1')
20762076
})
@@ -2081,7 +2081,7 @@ test.group('Make signed url', () => {
20812081
router.get('posts/:id', 'PostsController.index').domain('blog.adonisjs.com')
20822082
router.commit()
20832083

2084-
const url = router.makeSignedUrl('PostsController.index', { params: { id: 1 } })!
2084+
const url = router.makeSignedUrl('PostsController.index', { id: 1 })!
20852085
const qs = parse(url.split('?')[1])
20862086

20872087
assert.isTrue(url.startsWith('//blog.adonisjs.com/posts/1?signature='))
@@ -2094,7 +2094,7 @@ test.group('Make signed url', () => {
20942094
router.get('posts/:id', 'PostsController.index')
20952095
router.commit()
20962096

2097-
const url = router.makeSignedUrl('PostsController.index', { params: { id: 1 }, expiresIn: '1m' })!
2097+
const url = router.makeSignedUrl('PostsController.index', { id: 1, expiresIn: '1m' })!
20982098
const qs = parse(url.split('?')[1])
20992099

21002100
assert.equal(encryption.verifier.unsign(qs.signature as string), '/posts/1')
@@ -2107,7 +2107,7 @@ test.group('Make signed url', () => {
21072107
router.commit()
21082108

21092109
const url = router.makeSignedUrl('PostsController.index', {
2110-
params: { id: 1 },
2110+
id: 1,
21112111
qs: { page: 1 },
21122112
})!
21132113
const qs = parse(url.split('?')[1])
@@ -2126,7 +2126,7 @@ test.group('Make signed url', () => {
21262126
router.commit()
21272127

21282128
const url = router.makeSignedUrl('PostsController.index', {
2129-
params: { id: 1 },
2129+
id: 1,
21302130
qs: { page: 1 },
21312131
})!
21322132
const qs = parse(url.split('?')[1])

0 commit comments

Comments
 (0)