1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _GenericError = require('../error/GenericError');
|
8 |
|
9 | var _GenericError2 = _interopRequireDefault(_GenericError);
|
10 |
|
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
12 |
|
13 | // @server-side class Response {__CLEAR__}\nexports.default = Response;
|
14 |
|
15 | /**
|
16 | * Wrapper for the ExpressJS response, exposing only the necessary minimum.
|
17 | */
|
18 | class Response {
|
19 | static get $dependencies() {
|
20 | return [];
|
21 | }
|
22 |
|
23 | /**
|
24 | * Initializes the response.
|
25 | */
|
26 | constructor() {
|
27 | /**
|
28 | * The ExpressJS response object, or {@code null} if running at the
|
29 | * client side.
|
30 | *
|
31 | * @type {?Express.Response}
|
32 | */
|
33 | this._response = null;
|
34 |
|
35 | /**
|
36 | * It is flag for sent response for request.
|
37 | *
|
38 | * @type {boolean}
|
39 | */
|
40 | this._isSent = false;
|
41 |
|
42 | /**
|
43 | * HTTP Status code.
|
44 | *
|
45 | * @type {number}
|
46 | */
|
47 | this._status = 500;
|
48 |
|
49 | /**
|
50 | * The content of response.
|
51 | *
|
52 | * @type {string}
|
53 | */
|
54 | this._content = '';
|
55 |
|
56 | /**
|
57 | * The rendered page state.
|
58 | *
|
59 | * @type {Object<string, *>}
|
60 | */
|
61 | this._pageState = {};
|
62 |
|
63 | /**
|
64 | * Internal cookie storage for Set-Cookie header.
|
65 | *
|
66 | * @type {Map<string, {
|
67 | * value: string,
|
68 | * options: {domain: string=, expires: (number|string)=}
|
69 | * }>}
|
70 | */
|
71 | this._internalCookieStorage = new Map();
|
72 |
|
73 | /**
|
74 | * Transform function for cookie value.
|
75 | *
|
76 | * @type {{encode: function, decode: function}}
|
77 | */
|
78 | this._cookieTransformFunction = {
|
79 | encode: value => value,
|
80 | decode: value => value
|
81 | };
|
82 | }
|
83 |
|
84 | /**
|
85 | * Initializes this response wrapper with the provided ExpressJS response
|
86 | * object.
|
87 | *
|
88 | * @param {?Express.Response} response The ExpressJS response, or
|
89 | * {@code null} if the code is running at the client side.
|
90 | * @param {{
|
91 | * encode: function(string): string=,
|
92 | * decode: function(string): string
|
93 | * }=} cookieTransformFunction
|
94 | * @return {ima.router.Response} This response.
|
95 | */
|
96 | init(response, cookieTransformFunction = {}) {
|
97 | this._cookieTransformFunction = Object.assign(this._cookieTransformFunction, cookieTransformFunction);
|
98 | this._response = response;
|
99 | this._isSent = false;
|
100 | this._status = 500;
|
101 | this._content = '';
|
102 | this._pageState = {};
|
103 | this._internalCookieStorage = new Map();
|
104 |
|
105 | return this;
|
106 | }
|
107 |
|
108 | /**
|
109 | * Redirects the client to the specified location, with the specified
|
110 | * redirect HTTP response code.
|
111 | *
|
112 | * For full list of HTTP response status codes see
|
113 | * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
114 | *
|
115 | * Use this method only at the server side.
|
116 | *
|
117 | * @param {string} url The URL to which the client should be redirected.
|
118 | * @param {number=} [status=302] The HTTP status code to send to the
|
119 | * client.
|
120 | * @return {Response} This response.
|
121 | */
|
122 | redirect(url, status = 302) {
|
123 | if ($Debug) {
|
124 | if (this._isSent === true) {
|
125 | let params = this.getResponseParams();
|
126 | params.url = url;
|
127 |
|
128 | throw new _GenericError2.default('ima.router.Response:redirect The response has already ' + 'been sent. Check your workflow.', params);
|
129 | }
|
130 | }
|
131 |
|
132 | this._isSent = true;
|
133 | this._status = status;
|
134 | this._setCookieHeaders();
|
135 | this._response.redirect(status, url);
|
136 |
|
137 | return this;
|
138 | }
|
139 |
|
140 | /**
|
141 | * Sets the HTTP status code that will be sent to the client when the
|
142 | * response is sent.
|
143 | *
|
144 | * For full list of available response codes see
|
145 | * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
146 | *
|
147 | * Use this method only at the server side.
|
148 | *
|
149 | * @param {number} httpStatus HTTP response status code to send to the
|
150 | * client.
|
151 | * @return {Response} This response.
|
152 | */
|
153 | status(httpStatus) {
|
154 | if ($Debug) {
|
155 | if (this._isSent === true) {
|
156 | let params = this.getResponseParams();
|
157 |
|
158 | throw new _GenericError2.default('ima.router.Response:status The response has already ' + 'been sent. Check your workflow.', params);
|
159 | }
|
160 | }
|
161 |
|
162 | this._status = httpStatus;
|
163 | this._response.status(httpStatus);
|
164 |
|
165 | return this;
|
166 | }
|
167 |
|
168 | /**
|
169 | * Sends the response to the client with the provided content. Use this
|
170 | * method only at the server side.
|
171 | *
|
172 | * @param {string} content The response body.
|
173 | * @return {Response} This response.
|
174 | */
|
175 | send(content) {
|
176 | if ($Debug) {
|
177 | if (this._isSent === true) {
|
178 | let params = this.getResponseParams();
|
179 | params.content = content;
|
180 |
|
181 | throw new _GenericError2.default('ima.router.Response:send The response has already been ' + 'sent. Check your workflow.', params);
|
182 | }
|
183 | }
|
184 |
|
185 | this._isSent = true;
|
186 | this._content = content;
|
187 | this._setCookieHeaders();
|
188 | this._response.send(content);
|
189 |
|
190 | return this;
|
191 | }
|
192 |
|
193 | /**
|
194 | * Sets the rendered page state.
|
195 | *
|
196 | * @param {Object<string, *>} pageState The rendered page state.
|
197 | * @return {Response} This response.
|
198 | */
|
199 | setPageState(pageState) {
|
200 | if ($Debug) {
|
201 | if (this._isSent === true) {
|
202 | let params = this.getResponseParams();
|
203 | params.pageState = pageState;
|
204 |
|
205 | throw new _GenericError2.default('ima.router.Response:setState The response has already ' + 'been sent. Check your workflow.', params);
|
206 | }
|
207 | }
|
208 |
|
209 | this._pageState = pageState;
|
210 |
|
211 | return this;
|
212 | }
|
213 |
|
214 | /**
|
215 | * Sets a cookie, which will be sent to the client with the response.
|
216 | *
|
217 | * @param {string} name The cookie name.
|
218 | * @param {(boolean|number|string)} value The cookie value, will be
|
219 | * converted to string.
|
220 | * @param {{domain: string=, expires: (number|string)=, maxAge: number=}}
|
221 | * options Cookie attributes. Only the attributes listed in the type
|
222 | * annotation of this field are supported. For documentation and full
|
223 | * list of cookie attributes
|
224 | * see http://tools.ietf.org/html/rfc2965#page-5
|
225 | * @return {Response} This response.
|
226 | */
|
227 | setCookie(name, value, options = {}) {
|
228 | if ($Debug) {
|
229 | if (this._isSent === true) {
|
230 | let params = this.getResponseParams();
|
231 | params.name = name;
|
232 | params.value = value;
|
233 | params.options = options;
|
234 |
|
235 | throw new _GenericError2.default('ima.router.Response:setCookie The response has already ' + 'been sent. Check your workflow.', params);
|
236 | }
|
237 | }
|
238 |
|
239 | let advancedOptions = Object.assign({}, this._cookieTransformFunction, options);
|
240 |
|
241 | this._internalCookieStorage.set(name, {
|
242 | value,
|
243 | options: advancedOptions
|
244 | });
|
245 |
|
246 | return this;
|
247 | }
|
248 |
|
249 | /**
|
250 | * Return object which contains response status, content and rendered
|
251 | * page state.
|
252 | *
|
253 | * @return {{status: number, content: string, pageState: Object<string, *>}}
|
254 | */
|
255 | getResponseParams() {
|
256 | return {
|
257 | status: this._status,
|
258 | content: this._content,
|
259 | pageState: this._pageState
|
260 | };
|
261 | }
|
262 |
|
263 | /**
|
264 | * Return true if response is sent from server to client.
|
265 | *
|
266 | * @return {boolean}
|
267 | */
|
268 | isResponseSent() {
|
269 | return this._isSent;
|
270 | }
|
271 |
|
272 | /**
|
273 | * Set cookie headers for response.
|
274 | */
|
275 | _setCookieHeaders() {
|
276 | for (let [name, param] of this._internalCookieStorage) {
|
277 | let options = this._prepareCookieOptionsForExpress(param.options);
|
278 | this._response.cookie(name, param.value, options);
|
279 | }
|
280 | }
|
281 |
|
282 | /**
|
283 | * Prepares cookie options for Express.
|
284 | *
|
285 | * @param {{domain: string=, expires: (number|string)=, maxAge: number=}}
|
286 | * options Cookie attributes. Only the attributes listed in the type
|
287 | * annotation of this field are supported. For documentation and full
|
288 | * list of cookie attributes
|
289 | * see http://tools.ietf.org/html/rfc2965#page-5
|
290 | * @return {Object} Cookie options prepared for Express.
|
291 | */
|
292 | _prepareCookieOptionsForExpress(options) {
|
293 | let expressOptions = Object.assign({}, options);
|
294 |
|
295 | if (typeof expressOptions.maxAge === 'number') {
|
296 | expressOptions.maxAge *= 1000;
|
297 | } else {
|
298 | delete expressOptions.maxAge;
|
299 | }
|
300 |
|
301 | return expressOptions;
|
302 | }
|
303 | }
|
304 | exports.default = Response;
|
305 |
|
306 | typeof $IMA !== 'undefined' && $IMA !== null && $IMA.Loader && $IMA.Loader.register('ima/router/Response', [], function (_export, _context) {
|
307 | ;
|
308 | return {
|
309 | setters: [],
|
310 | execute: function () {
|
311 | _export('default', exports.default);
|
312 | }
|
313 | };
|
314 | });
|