Skip to content
Snippets Groups Projects
Commit bdcace05 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Added support for request path that are independent of route paths. Closes 67.

parent 39684090
Branches
No related tags found
1 merge request!111Resolve "Allow routes with none graph API paths"
Pipeline #235189 passed
......@@ -122,4 +122,18 @@ describe('createRequestForRoute', () => {
)
expect(result).toEqual({key: {requestKey: 'value'}})
})
it('works with requestPath', () => {
const result = createRequestForRoute(
[{route: {requestPath: 'some/path'}} as unknown as RouteMatch],
() => ({requestKey: 'value'}),
)
expect(result).toEqual({some: {path: {requestKey: 'value'}}})
})
it('works with requestPath function', () => {
const result = createRequestForRoute(
[{route: {requestKey: () => 'some/path'}} as unknown as RouteMatch],
() => ({requestKey: 'value'}),
)
expect(result).toEqual({some: {path: {requestKey: 'value'}}})
})
})
import lodash from 'lodash'
import {User} from 'oidc-client-ts'
import {graphApi} from '../../utils/api'
import {resolveAllMDefs} from '../../utils/metainfo'
import {JSONObject} from '../../utils/types'
import {assert} from '../../utils/utils'
import {DefaultSearch, LoaderResult, RouteMatch} from './types'
export class DoesNotExistError extends Error {
......@@ -58,8 +58,33 @@ export function getResponseForRoute(
return getResponseForPath(path, response)
}
export function getRequestKey(match: RouteMatch) {
if (!match.route.requestKey) {
function getRequestPath(
match: RouteMatch,
parentPath?: string,
): string | undefined {
if (match.route.requestPath) {
if (typeof match.route.requestPath === 'string') {
return match.route.requestPath
} else {
return match.route.requestPath({
...match,
search: match.search as DefaultSearch,
})
}
}
const key = getRequestKey(match)
if (key === '') {
return parentPath
}
if (parentPath === undefined) {
return key
} else {
return `${parentPath}/${key}`
}
}
function getRequestKey(match: RouteMatch) {
if (match.route.requestKey === undefined) {
return match.path
}
if (typeof match.route.requestKey === 'string') {
......@@ -75,24 +100,32 @@ export function createRequestForRoute(
match: RouteMatch[],
getRequest: (match: RouteMatch, index: number) => JSONObject | undefined,
): JSONObject {
const request = {} as JSONObject
const lastIndexWithRequest = match.findLastIndex(getRequest)
match.slice(0, lastIndexWithRequest + 1).reduce((request, match, index) => {
const next = getRequest(match, index) || {}
const key = getRequestKey(match)
if (key === '') {
lodash.merge(request, next)
return request
}
if (request[key] !== undefined) {
lodash.merge(request[key], next)
} else {
request[key] = next
const requests: {[path: string]: JSONObject} = {}
let parentPath: string | undefined
match.forEach((match, index) => {
const request = getRequest(match, index)
const path = getRequestPath(match, parentPath)
if (request) {
assert(path !== undefined, 'Request for empty paths are not supported.')
requests[path] = request
}
return request[key] as JSONObject
}, request)
parentPath = path
})
const rootRequest = {} as JSONObject
Object.entries(requests).forEach(([path, request]) => {
const segments = path.split('/')
let currentRequest: JSONObject = rootRequest
segments.forEach((key) => {
if (currentRequest[key] === undefined) {
currentRequest[key] = {}
}
currentRequest = currentRequest[key] as JSONObject
})
Object.assign(currentRequest, request)
})
return request
return rootRequest
}
export default function loader(
......
......@@ -262,6 +262,18 @@ export type Route<
| string
| ((locationData: RouteMatch<Request, Response, Search>) => string)
/**
* An optional path or function that produces a path. The path will
* replace the API path usually derived from the `path` property of the route
* and its parent routes. Similar to request key, but for the whole path.
*
* This applies to the whole route including all child routes.
* TODO Are there cases where this is bad? Should this be configurable?
*/
requestPath?:
| string
| ((locationData: RouteMatch<Request, Response, Search>) => string)
/**
* An optional request or function that produces a request. The request
* has to satisfy the type `Request`. The request is used to create
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment