1 | /**
|
2 | * @file Defines the BaseResponse class.
|
3 | *
|
4 | * @author Luke Chavers <luke@c2cschools.com>
|
5 | * @author Kevin Sanders <kevin@c2cschools.com>
|
6 | * @since 5.0.0
|
7 | * @license See LICENSE.md for details about licensing.
|
8 | * @copyright 2017 C2C Schools, LLC
|
9 | */
|
10 |
|
11 | ;
|
12 |
|
13 | const BaseClass = require( "@corefw/common" ).common.BaseClass;
|
14 |
|
15 | /**
|
16 | * This is the base class for all API responses.
|
17 | *
|
18 | * @abstract
|
19 | * @memberOf Response
|
20 | * @extends Common.BaseClass
|
21 | */
|
22 | module.exports = class BaseResponse extends BaseClass {
|
23 |
|
24 | /**
|
25 | * Stores a reference to the {@link Request.Request} object that this
|
26 | * object is being used to respond to.
|
27 | *
|
28 | * @public
|
29 | * @type {Request.Request}
|
30 | * @default null
|
31 | */
|
32 | get request() {
|
33 |
|
34 | const me = this;
|
35 |
|
36 | return me.getConfigValue( "request", null );
|
37 | }
|
38 |
|
39 | set request( /** Request.Request */ val ) {
|
40 |
|
41 | const me = this;
|
42 |
|
43 | me.setConfigValue( "request", val );
|
44 | }
|
45 |
|
46 | /**
|
47 | * A reference to the current execution context.
|
48 | *
|
49 | * @public
|
50 | * @type {ExecutionContext.BaseExecutionContext}
|
51 | * @readonly
|
52 | */
|
53 | get context() {
|
54 |
|
55 | const me = this;
|
56 |
|
57 | if ( me.request === null ) {
|
58 |
|
59 | return null;
|
60 | }
|
61 |
|
62 | return me.request.context;
|
63 | }
|
64 |
|
65 | /**
|
66 | * The data portion of the response.
|
67 | *
|
68 | * @public
|
69 | * @type {Object}
|
70 | * @default {}
|
71 | */
|
72 | get data() {
|
73 |
|
74 | const me = this;
|
75 |
|
76 | return me.getConfigValue( "data", {} );
|
77 | }
|
78 |
|
79 | set data( /** Object */ val ) {
|
80 |
|
81 | const me = this;
|
82 |
|
83 | me.setConfigValue( "data", val );
|
84 | }
|
85 |
|
86 | /**
|
87 | * The endpoint that is responding.
|
88 | *
|
89 | * @public
|
90 | * @type {?Endpoint.BaseEndpoint}
|
91 | * @default null
|
92 | */
|
93 | get endpoint() {
|
94 |
|
95 | const me = this;
|
96 |
|
97 | return me.getConfigValue( "endpoint", null );
|
98 | }
|
99 |
|
100 | set endpoint( /** ?Endpoint.BaseEndpoint */ val ) {
|
101 |
|
102 | const me = this;
|
103 |
|
104 | me.setConfigValue( "endpoint", val );
|
105 | }
|
106 |
|
107 | /**
|
108 | * The operationId (class name) of the endpoint that is responding.
|
109 | *
|
110 | * @public
|
111 | * @type {?string}
|
112 | * @default null
|
113 | */
|
114 | get operationId() {
|
115 |
|
116 | const me = this;
|
117 |
|
118 | if ( me.endpoint === null ) {
|
119 |
|
120 | return null;
|
121 | }
|
122 |
|
123 | return me.endpoint.operationId;
|
124 | }
|
125 |
|
126 | /**
|
127 | * The name of the service in which the responding endpoint resides.
|
128 | *
|
129 | * @public
|
130 | * @type {?string}
|
131 | * @readonly
|
132 | */
|
133 | get serviceName() {
|
134 |
|
135 | const me = this;
|
136 |
|
137 | if ( me.endpoint === null ) {
|
138 |
|
139 | return null;
|
140 | }
|
141 |
|
142 | return me.endpoint.serviceName;
|
143 | }
|
144 |
|
145 | /**
|
146 | * The version of the service in which the responding endpoint resides.
|
147 | *
|
148 | * @public
|
149 | * @type {?string}
|
150 | * @readonly
|
151 | */
|
152 | get serviceVersion() {
|
153 |
|
154 | const me = this;
|
155 |
|
156 | if ( me.endpoint === null ) {
|
157 |
|
158 | return null;
|
159 | }
|
160 |
|
161 | return me.endpoint.serviceVersion;
|
162 | }
|
163 |
|
164 | /**
|
165 | * The primary model of the responding endpoint.
|
166 | *
|
167 | * @public
|
168 | * @type {?string}
|
169 | * @default null
|
170 | */
|
171 | get primaryModel() {
|
172 |
|
173 | const me = this;
|
174 |
|
175 | return me.getConfigValue( "primaryModel", null );
|
176 | }
|
177 |
|
178 | // noinspection JSUnusedGlobalSymbols
|
179 | set primaryModel( /** ?string */ val ) {
|
180 |
|
181 | const me = this;
|
182 |
|
183 | me.setConfigValue( "primaryModel", val );
|
184 | }
|
185 |
|
186 | /**
|
187 | * The status code of this response, which should correlate to an
|
188 | * Http status code.
|
189 | *
|
190 | * @public
|
191 | * @type {number}
|
192 | * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
193 | * @default 200
|
194 | */
|
195 | get statusCode() {
|
196 |
|
197 | const me = this;
|
198 |
|
199 | return me.getConfigValue( "statusCode", 200 );
|
200 | }
|
201 |
|
202 | set statusCode( /** number */ val ) {
|
203 |
|
204 | const me = this;
|
205 |
|
206 | me.setConfigValue( "statusCode", val );
|
207 | }
|
208 |
|
209 | /**
|
210 | * The body of the response.
|
211 | *
|
212 | * @public
|
213 | * @type {Object}
|
214 | * @readonly
|
215 | */
|
216 | get body() {
|
217 |
|
218 | const me = this;
|
219 |
|
220 | return me._createResponseBody();
|
221 | }
|
222 |
|
223 | /**
|
224 | * The body of the response, serialized into a JSON string.
|
225 | *
|
226 | * @public
|
227 | * @type {string}
|
228 | * @readonly
|
229 | */
|
230 | get strBody() {
|
231 |
|
232 | const me = this;
|
233 |
|
234 | return JSON.stringify( me.body );
|
235 | }
|
236 |
|
237 | /**
|
238 | * The http headers that should be included in the response if the client
|
239 | * is invoking this endpoint by way of an http API or proxy.
|
240 | *
|
241 | * @public
|
242 | * @type {Object}
|
243 | * @readonly
|
244 | */
|
245 | get headers() {
|
246 |
|
247 | const me = this;
|
248 |
|
249 | return {
|
250 | "x-series-uuid": me.seriesId,
|
251 | };
|
252 | }
|
253 |
|
254 | /**
|
255 | * The seriesId (which is a UUID) for this response. This is mirror/alias
|
256 | * of {@link ExecutionContext.BaseExecutionContext#seriesId}.
|
257 | *
|
258 | * @public
|
259 | * @type {?string}
|
260 | * @readonly
|
261 | */
|
262 | get seriesId() {
|
263 |
|
264 | const me = this;
|
265 |
|
266 | if ( me.context === null ) {
|
267 |
|
268 | return null;
|
269 | }
|
270 |
|
271 | return me.context.seriesId;
|
272 | }
|
273 |
|
274 | /**
|
275 | * The requestId (which is a UUID) for this response. This is mirror/alias
|
276 | * of {@link ExecutionContext.BaseExecutionContext#requestId}.
|
277 | *
|
278 | * @public
|
279 | * @type {?string}
|
280 | * @readonly
|
281 | */
|
282 | get requestId() {
|
283 |
|
284 | const me = this;
|
285 |
|
286 | if ( me.context === null ) {
|
287 |
|
288 | return null;
|
289 | }
|
290 |
|
291 | return me.context.requestId;
|
292 | }
|
293 |
|
294 | /**
|
295 | * The api stage for this response. This is mirror/alias of
|
296 | * {@link ExecutionContext.BaseExecutionContext#apiStage}.
|
297 | *
|
298 | * @public
|
299 | * @type {?string}
|
300 | * @readonly
|
301 | */
|
302 | get apiStage() {
|
303 |
|
304 | const me = this;
|
305 |
|
306 | if ( me.context === null ) {
|
307 |
|
308 | return null;
|
309 | }
|
310 |
|
311 | return me.context.apiStage;
|
312 | }
|
313 |
|
314 | /**
|
315 | * Indicates whether or not this response represents an error.
|
316 | *
|
317 | * @public
|
318 | * @type {boolean}
|
319 | * @default false
|
320 | */
|
321 | get isError() {
|
322 |
|
323 | const me = this;
|
324 |
|
325 | return me.getConfigValue( "isError", false );
|
326 | }
|
327 |
|
328 | // noinspection JSUnusedGlobalSymbols
|
329 | set isError( /** boolean */ val ) {
|
330 |
|
331 | const me = this;
|
332 |
|
333 | me.setConfigValue( "isError", val );
|
334 | }
|
335 |
|
336 | /**
|
337 | * Returns a plain object representation of this response object.
|
338 | *
|
339 | * @public
|
340 | * @param {string} [bodyProperty="strBody"] - Indicates how the body should
|
341 | * be formatted within the returned object.
|
342 | * @returns {{statusCode: *, headers: *, body: *}} Plain object
|
343 | * representation of this response object.
|
344 | */
|
345 | toPlainObject( bodyProperty ) {
|
346 |
|
347 | const me = this;
|
348 |
|
349 | if ( bodyProperty !== "body" ) {
|
350 |
|
351 | bodyProperty = "strBody";
|
352 | }
|
353 |
|
354 | return {
|
355 | statusCode : me.statusCode,
|
356 | headers : me.headers,
|
357 | body : me[ bodyProperty ],
|
358 | };
|
359 | }
|
360 |
|
361 | /**
|
362 | * Serializes this collection into a JSON-API compatible object.
|
363 | *
|
364 | * @private
|
365 | * @returns {Object} JSON-API compatible object.
|
366 | */
|
367 | _serializeToJsonApiObject() {
|
368 |
|
369 | const me = this;
|
370 |
|
371 | return me.toPlainObject( "strBody" );
|
372 | }
|
373 |
|
374 | /**
|
375 | * Creates a JSON-API compatible scaffold for the response body [object].
|
376 | *
|
377 | * @private
|
378 | * @returns {Object} Response body.
|
379 | */
|
380 | _createResponseBody() {
|
381 |
|
382 | const me = this;
|
383 |
|
384 | return {
|
385 | jsonapi: {
|
386 | version: "1.0",
|
387 | },
|
388 | meta: {
|
389 | requestId : me.requestId,
|
390 | seriesId : me.seriesId,
|
391 | operationId : me.operationId,
|
392 | stage : me.apiStage,
|
393 | service : {
|
394 | name : me.endpoint.serviceName,
|
395 | version : me.endpoint.serviceVersion,
|
396 | },
|
397 | },
|
398 | };
|
399 | }
|
400 | };
|