-
Notifications
You must be signed in to change notification settings - Fork 3
/
route-model.ts
118 lines (103 loc) · 3.47 KB
/
route-model.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { Request, RequestHandler } from 'express';
import { CallbackType, HandlerType, RouteData, VariantData } from '../types';
import {
DEFAULT_VARIANT,
X_REQUEST_SESSION,
X_REQUEST_VARIANT,
} from '../utils/constants';
import logger from '../utils/logger';
import { getValidMethod } from '../utils/method-utils';
import { SessionState } from './sessionState';
export class Route {
private _activeVariant = 'default';
private _variants: Map<string, VariantData> = new Map<string, VariantData>();
private routeData: RouteData;
private sessionState: SessionState;
public getVariants() {
return this._variants;
}
public getActiveVariantId(request?: Request) {
const variantRequestHeader = request?.get(X_REQUEST_VARIANT);
const sessionVariantRequestHeader = request?.get(X_REQUEST_SESSION);
const routeStateVariant = this._activeVariant;
let sessionVariant = undefined;
if (sessionVariantRequestHeader) {
sessionVariant = this.sessionState.getSessionVariantStateForRoute(
sessionVariantRequestHeader,
this.id
);
}
return variantRequestHeader || sessionVariant || routeStateVariant;
}
// public getActiveVariant(activeVariantId: string) {
public getActiveVariant() {
// return this._variants.get(activeVariantId);
return this._activeVariant;
}
public id: string;
public method: string;
public path: string | RegExp;
constructor(routeData: RouteData, sessionState: SessionState) {
this.routeData = routeData;
this.id = routeData.id;
this.method = getValidMethod(routeData.method);
this.path = routeData.path;
this.sessionState = sessionState;
}
/**
* Called to process express endpoint of this mock route
* @param req
* @param res
* @param next
*/
public processRequest: RequestHandler = (req, res, next) => {
let callback: CallbackType;
let handler: HandlerType;
const activeVariant = this.getActiveVariantId(req);
const hasVariant = this._variants.has(activeVariant);
if (!hasVariant || activeVariant === DEFAULT_VARIANT) {
callback = this.routeData.callback;
handler = this.routeData.handler;
} else {
callback = this._variants.get(activeVariant).callback;
handler = this._variants.get(activeVariant).handler;
}
logger.info(
`Processing request for path ${this.path} with active variant ${this._activeVariant} of variants with size ${this._variants.size}`
);
if (callback) {
callback(req, res, this);
} else if (handler) {
handler.call(this, req, res);
} else {
res.send('no match');
}
};
public setVariant = (variantId: string) => {
if (this._variants.has(variantId) || variantId === 'default') {
logger.info(
'Setting active variant for ' + this.path + ' to ' + variantId
);
this._activeVariant = variantId;
} else {
logger.warn(
`Could not find variant "${variantId}" in route ${this.id} (${this.method} ${this.routeData.path}})`
);
// return new Error('no variants found with id: ' + variantId);
}
return this;
};
/**
* Add variant to this route
* Returns everything to allow for chaining e.g. mezzo.route(x).variant(y).variant(z);
* @param variantData
* @returns
*/
public variant = (variantData: VariantData) => {
this._variants.set(variantData.id, variantData);
logger.info(
`Adding to variants, size of ${this.path} is now ${this._variants.size}`
);
return this;
};
}