2022-08-11 17:42:21 +03:00
|
|
|
const debug = require('@tryghost/debug')('frame');
|
2018-10-05 01:50:45 +03:00
|
|
|
const _ = require('lodash');
|
|
|
|
|
2019-05-06 15:24:12 +03:00
|
|
|
/**
|
|
|
|
* @description The "frame" holds all information of a request.
|
|
|
|
*
|
|
|
|
* Each party can modify the frame by reference.
|
|
|
|
* A request hits a lot of stages in the API implementation and that's why modification by reference was the
|
|
|
|
* easiest to use. We always have access to the original input, we never loose track of it.
|
|
|
|
*/
|
2018-10-05 01:50:45 +03:00
|
|
|
class Frame {
|
2019-02-13 18:59:10 +03:00
|
|
|
constructor(obj = {}) {
|
2018-10-05 01:50:45 +03:00
|
|
|
this.original = obj;
|
|
|
|
|
2019-05-06 15:24:12 +03:00
|
|
|
/**
|
|
|
|
* options: Query params, url params, context and custom options
|
|
|
|
* data: Body or if the ctrl wants query/url params inside body
|
|
|
|
* user: Logged in user
|
|
|
|
* file: Uploaded file
|
|
|
|
* files: Uploaded files
|
|
|
|
* apiType: Content or admin api access
|
2022-08-21 18:31:41 +03:00
|
|
|
* docName: The endpoint name, e.g. "posts"
|
|
|
|
* method: The method name, e.g. "browse"
|
2019-05-06 15:24:12 +03:00
|
|
|
*/
|
2018-10-05 01:50:45 +03:00
|
|
|
this.options = {};
|
|
|
|
this.data = {};
|
|
|
|
this.user = {};
|
|
|
|
this.file = {};
|
|
|
|
this.files = [];
|
2019-02-25 21:52:45 +03:00
|
|
|
this.apiType = null;
|
2022-08-21 18:31:41 +03:00
|
|
|
this.docName = null;
|
|
|
|
this.method = null;
|
|
|
|
this.response = null;
|
2018-10-05 01:50:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-05-06 15:24:12 +03:00
|
|
|
* @description Configure the frame.
|
|
|
|
*
|
|
|
|
* If you instantiate a new frame, all the data you pass in, land in `this.original`. This is helpful
|
|
|
|
* for debugging to see what the original input was.
|
|
|
|
*
|
|
|
|
* This function will prepare the incoming data for further processing.
|
2018-10-05 01:50:45 +03:00
|
|
|
* Based on the API ctrl implemented, this fn will pick allowed properties to either options or data.
|
|
|
|
*/
|
|
|
|
configure(apiConfig) {
|
|
|
|
debug('configure');
|
|
|
|
|
|
|
|
if (apiConfig.options) {
|
|
|
|
if (typeof apiConfig.options === 'function') {
|
|
|
|
apiConfig.options = apiConfig.options(this);
|
|
|
|
}
|
|
|
|
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(this.original, 'query')) {
|
2018-10-05 01:50:45 +03:00
|
|
|
Object.assign(this.options, _.pick(this.original.query, apiConfig.options));
|
|
|
|
}
|
|
|
|
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(this.original, 'params')) {
|
2018-10-05 01:50:45 +03:00
|
|
|
Object.assign(this.options, _.pick(this.original.params, apiConfig.options));
|
|
|
|
}
|
|
|
|
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(this.original, 'options')) {
|
2018-10-05 01:50:45 +03:00
|
|
|
Object.assign(this.options, _.pick(this.original.options, apiConfig.options));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.options.context = this.original.context;
|
|
|
|
|
|
|
|
if (this.original.body && Object.keys(this.original.body).length) {
|
2019-03-05 00:59:13 +03:00
|
|
|
this.data = _.cloneDeep(this.original.body);
|
2018-10-05 01:50:45 +03:00
|
|
|
} else {
|
|
|
|
if (apiConfig.data) {
|
|
|
|
if (typeof apiConfig.data === 'function') {
|
|
|
|
apiConfig.data = apiConfig.data(this);
|
|
|
|
}
|
|
|
|
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(this.original, 'query')) {
|
2018-10-05 01:50:45 +03:00
|
|
|
Object.assign(this.data, _.pick(this.original.query, apiConfig.data));
|
|
|
|
}
|
|
|
|
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(this.original, 'params')) {
|
2018-10-05 01:50:45 +03:00
|
|
|
Object.assign(this.data, _.pick(this.original.params, apiConfig.data));
|
|
|
|
}
|
|
|
|
|
2019-07-05 14:40:43 +03:00
|
|
|
if (Object.prototype.hasOwnProperty.call(this.original, 'options')) {
|
2018-10-05 01:50:45 +03:00
|
|
|
Object.assign(this.data, _.pick(this.original.options, apiConfig.data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.user = this.original.user;
|
|
|
|
this.file = this.original.file;
|
|
|
|
this.files = this.original.files;
|
|
|
|
|
|
|
|
debug('original', this.original);
|
|
|
|
debug('options', this.options);
|
|
|
|
debug('data', this.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = Frame;
|