fix(core): fixed problem with path concatenation when wildcard sign appears
MODIFY
packages/@integration/test/integration.spec.ts
packages/@integration/test/integration.spec.ts
@@ -20,8 +20,7 @@ describe('API integration', () => {
.get('/api/v2')
.expect(200, '"API version: v2"'));
- // @TODO: fix an error with `*` after placeholder path
- xtest('GET: /api/v1/foo triggers 404 effect', async () =>
+ test('GET: /api/v1/foo triggers 404 effect', async () =>
request(app)
.get('/api/v1/foo')
.expect(404, {

MODIFY
packages/core/src/router/router.factory.ts
packages/core/src/router/router.factory.ts
@@ -20,15 +20,17 @@ export const factorizeRouting = (
const routing: Routing = [];
routes.forEach(route => {
+ const concatedPath = parentPath + '/' + route.path;
+
if (isRouteEffectGroup(route)) {
return routing.push(...factorizeRouting(
route.effects,
[...middleware, ...route.middlewares],
- parentPath + route.path,
+ concatedPath,
));
}
- const { regExp, parameters } = factorizeRegExpWithParams(parentPath + route.path);
+ const { regExp, parameters } = factorizeRegExpWithParams(concatedPath);
const foundRoute = routing.find(route => route.regExp.source === regExp.source);
const method: RoutingMethod = {
effect: route.effect,

MODIFY
packages/core/src/router/specs/router.factory.spec.ts
packages/core/src/router/specs/router.factory.spec.ts
@@ -15,63 +15,65 @@ describe('Router factory', () => {
test('#factorizeRouting factorizes routing with nested groups', () => {
// given
const m$: Middleware = req$ => req$;
- const e1$: Effect = req$ => req$.pipe(mapTo({ body: 'test1' }));
- const e2$: Effect = req$ => req$.pipe(mapTo({ body: 'test2' }));
- const e3$: Effect = req$ => req$.pipe(mapTo({ body: 'test3' }));
- const e4$: Effect = req$ => req$.pipe(mapTo({ body: 'test4' }));
-
- const route1: RouteEffect = { path: '/', method: 'GET', effect: e1$ };
- const route2: RouteEffect = { path: '/', method: 'GET', effect: e2$ };
- const route3: RouteEffect = { path: '/', method: 'GET', effect: e3$ };
- const route4: RouteEffect = { path: '/', method: 'POST', effect: e4$ };
+ const e$: Effect = req$ => req$.pipe(mapTo({ body: 'test' }));
const routeGroupNested: RouteEffectGroup = {
path: '/nested',
- effects: [route3],
+ effects: [{ path: '/', method: 'GET', effect: e$ }],
middlewares: [m$],
};
const routeGroup: RouteEffectGroup = {
- path: '/group',
- effects: [route2, routeGroupNested],
+ path: '/:id',
+ effects: [
+ { path: '/', method: 'GET', effect: e$ },
+ { path: '/', method: 'POST', effect: e$ },
+ routeGroupNested,
+ { path: '*', method: '*', effect: e$ },
+ ],
middlewares: [m$],
};
+ const routing: (RouteEffect | RouteEffectGroup)[] = [
+ { path: '/', method: 'GET', effect: e$ },
+ routeGroup,
+ ];
+
// when
effectsCombiner.combineMiddlewareEffects = jest.fn(() => m$);
-
- const factorizedRouting = factorizeRouting([
- route1,
- routeGroup,
- route4
- ]);
+ const factorizedRouting = factorizeRouting(routing);
// then
expect(factorizedRouting).toEqual([
{
regExp: /^\/?$/,
- methods: { GET: { effect: e1$ }, POST: { effect: e4$ } },
+ methods: { GET: { effect: e$, middleware: undefined, parameters: undefined } },
+ },
+ {
+ regExp: /^\/([^\/]+)\/?$/,
+ methods: {
+ GET: { middleware: m$, effect: e$, parameters: ['id'] },
+ POST: { middleware: m$, effect: e$, parameters: ['id'] },
+ },
},
{
- regExp: /^\/group\/?$/,
- methods: { GET: { middleware: m$, effect: e2$ } },
+ regExp: /^\/([^\/]+)\/nested\/?$/,
+ methods: { GET: { middleware: m$, effect: e$, parameters: ['id'] } },
},
{
- regExp: /^\/group\/nested\/?$/,
- methods: { GET: { middleware: m$, effect: e3$ } },
+ regExp: /^\/([^\/]+)\/.*?$/,
+ methods: { '*': { middleware: m$, effect: e$, parameters: ['id'] } },
},
] as Routing);
});
test('#factorizeRouting throws error if route is redefined', () => {
// given
- const e1$: Effect = req$ => req$.pipe(mapTo({ body: 'test1' }));
- const e2$: Effect = req$ => req$.pipe(mapTo({ body: 'test2' }));
- const e3$: Effect = req$ => req$.pipe(mapTo({ body: 'test3' }));
+ const e$: Effect = req$ => req$.pipe(mapTo({ body: 'test' }));
- const route1: RouteEffect = { path: '/test', method: 'GET', effect: e1$ };
- const route2: RouteEffect = { path: '/test', method: 'GET', effect: e2$ };
- const route3: RouteEffect = { path: '/test/foo', method: 'GET', effect: e3$ };
+ const route1: RouteEffect = { path: '/test', method: 'GET', effect: e$ };
+ const route2: RouteEffect = { path: '/test', method: 'GET', effect: e$ };
+ const route3: RouteEffect = { path: '/test/foo', method: 'GET', effect: e$ };
// when
const error = () => factorizeRouting([

MODIFY
packages/core/src/router/urlParams.factory.ts
packages/core/src/router/urlParams.factory.ts
@@ -15,6 +15,7 @@ export const factorizeRegExpWithParams = (path: string): ParametricRegExp => {
.replace(/([?./\\()[\]{}^$])/g, '\\$1') /* Escape all regex characters */
.replace(pathParameters, `([^\\/]+)`) /* Translate all path parameters to regex groups */
.replace(/\*/g, '.*?') /* Translate all stars to a wildcard */
+ .replace(/\/{2,}/g, '/') /* Remove duplicated backslashes */
.replace(/([/\\])$/, '$1?'); /* Last slash/backslash is always optional */
return {

fix(core): fixed problem with path concatenation when wildcard sign appears