Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 119 120 121 122 123 124 125 | 1x 1x 1x 420x 513x 392x 225x 700x 225x 225x 202x 23x 143x 23x 288x 225x 225x 143x 143x 143x 143x 44x 99x 86x 16x 70x 8x 62x 18x 44x 57x 1x | 'use strict';
const _ = require('lodash');
const jsonMask = require('json-mask');
const WILDCARD_CHAR = '*';
class PartialFieldManager {
/**
*
* @param {string | undefined} partialFieldsString
*/
constructor(partialFieldsString = null) {
// Init partial fields is wildcard
this._partialFieldsString = partialFieldsString || WILDCARD_CHAR;
}
/**
* @returns {string}
*/
getPartialFieldsString() {
return this._partialFieldsString || WILDCARD_CHAR;
}
/**
* @param {string} partialFieldsString
*/
setPartialFieldsString(partialFieldsString) {
this._partialFieldsString = partialFieldsString || WILDCARD_CHAR;
}
/**
* Reduce the includes depends on partial fields (X-Fields header).
* Not include the resources that not included in partial fields
* @param {Array|string} includes
* @returns Array
*/
reduceIncludes(includes) {
if (typeof includes === 'string') {
includes = includes.split(',').map((item) => item.trim());
}
const parsedPartialFields = this._parsePartialFields(this.getPartialFieldsString());
if (!parsedPartialFields || this._isIncludeAllFields(parsedPartialFields)) {
return includes;
}
const reducedIncludes = includes.filter((include) =>
this._isIncludedField(include, parsedPartialFields),
);
return reducedIncludes;
}
/**
* Return filtered data
* @param {*} data
* @returns
*/
toJSON(data) {
return jsonMask(data, this.getPartialFieldsString());
}
/**
* Check include all fields
* @param {Object} parsedProperties
* @returns
*/
_isIncludeAllFields(parsedProperties) {
// When there is wildcard on first level, it is required all fields
return _.has(parsedProperties, WILDCARD_CHAR);
}
/**
* @param {string} partialFieldsString
* @returns {Record<string, string>|null}
*/
_parsePartialFields(partialFieldsString) {
return jsonMask.compile(partialFieldsString);
}
/**
* Check the include is required in partial fields
* @param {string} include
* @param {Record<string, string>} parsedPartialFields
* @returns
*/
_isIncludedField(include, parsedPartialFields) {
Iif (_.has(parsedPartialFields, WILDCARD_CHAR)) {
return true;
}
const nested = include.split('.');
// Take the first level
let path = nested.shift();
// Return since it does not exist in partial fields
if (!_.has(parsedPartialFields, path)) {
return false;
}
for (const subPart of nested) {
// wildcard will return all sub-parts
if (_.has(parsedPartialFields, `${path}.properties.${WILDCARD_CHAR}`)) {
return true;
}
// When partial fields contain only root path, take all sub-parts
// When mask: (order) => parsedPartialFields = {order: {type: "object"}}:
// Should take all includes [order.staff, order]
if (
_.has(parsedPartialFields, `${path}`) &&
!_.has(parsedPartialFields, `${path}.properties`)
) {
return true;
}
// Return false if subpart does not exist in properties list
if (!_.has(parsedPartialFields, `${path}.properties.${subPart}`)) {
return false;
}
// Continue next deeper path
path = `${path}.properties.${subPart}`;
}
return true;
}
}
module.exports = PartialFieldManager;
|