@strapi/utils 4.11.3 → 4.12.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/async.d.ts +10 -0
- package/dist/async.js +33 -0
- package/dist/async.js.map +1 -0
- package/dist/code-generator.d.ts +2 -0
- package/dist/code-generator.js +11 -0
- package/dist/code-generator.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/content-types.d.ts +60 -0
- package/dist/content-types.js +151 -0
- package/dist/content-types.js.map +1 -0
- package/dist/convert-query-params.d.ts +75 -0
- package/dist/convert-query-params.js +476 -0
- package/dist/convert-query-params.js.map +1 -0
- package/dist/env-helper.d.ts +18 -0
- package/dist/env-helper.js +84 -0
- package/dist/env-helper.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.js +100 -0
- package/dist/errors.js.map +1 -0
- package/dist/file.d.ts +16 -0
- package/dist/file.js +54 -0
- package/dist/file.js.map +1 -0
- package/dist/format-yup-error.d.ts +10 -0
- package/dist/format-yup-error.js +17 -0
- package/dist/format-yup-error.js.map +1 -0
- package/dist/hooks.d.ts +63 -0
- package/dist/hooks.js +89 -0
- package/dist/hooks.js.map +1 -0
- package/dist/import-default.d.ts +1 -0
- package/dist/import-default.js +9 -0
- package/dist/import-default.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/object-formatting.d.ts +3 -0
- package/dist/object-formatting.js +14 -0
- package/dist/object-formatting.js.map +1 -0
- package/dist/operators.d.ts +2 -0
- package/dist/operators.js +70 -0
- package/dist/operators.js.map +1 -0
- package/dist/pagination.d.ts +14 -0
- package/dist/pagination.js +80 -0
- package/dist/pagination.js.map +1 -0
- package/dist/parse-multipart.d.ts +8 -0
- package/dist/parse-multipart.js +36 -0
- package/dist/parse-multipart.js.map +1 -0
- package/dist/parse-type.d.ts +21 -0
- package/dist/parse-type.js +108 -0
- package/dist/parse-type.js.map +1 -0
- package/dist/policy.d.ts +41 -0
- package/dist/policy.js +109 -0
- package/dist/policy.js.map +1 -0
- package/dist/print-value.d.ts +2 -0
- package/dist/print-value.js +50 -0
- package/dist/print-value.js.map +1 -0
- package/dist/provider-factory.d.ts +29 -0
- package/dist/provider-factory.js +80 -0
- package/dist/provider-factory.js.map +1 -0
- package/dist/relations.d.ts +10 -0
- package/dist/relations.js +23 -0
- package/dist/relations.js.map +1 -0
- package/dist/sanitize/index.d.ts +23 -0
- package/dist/sanitize/index.js +135 -0
- package/dist/sanitize/index.js.map +1 -0
- package/dist/sanitize/sanitizers.d.ts +10 -0
- package/dist/sanitize/sanitizers.js +114 -0
- package/dist/sanitize/sanitizers.js.map +1 -0
- package/dist/sanitize/visitors/allowed-fields.d.ts +3 -0
- package/{lib → dist}/sanitize/visitors/allowed-fields.js +17 -32
- package/dist/sanitize/visitors/allowed-fields.js.map +1 -0
- package/dist/sanitize/visitors/index.d.ts +7 -0
- package/dist/sanitize/visitors/index.js +21 -0
- package/dist/sanitize/visitors/index.js.map +1 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.d.ts +3 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.js +10 -0
- package/dist/sanitize/visitors/remove-dynamic-zones.js.map +1 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.d.ts +3 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.js +10 -0
- package/dist/sanitize/visitors/remove-morph-to-relations.js.map +1 -0
- package/dist/sanitize/visitors/remove-password.d.ts +3 -0
- package/dist/sanitize/visitors/remove-password.js +9 -0
- package/dist/sanitize/visitors/remove-password.js.map +1 -0
- package/dist/sanitize/visitors/remove-private.d.ts +3 -0
- package/dist/sanitize/visitors/remove-private.js +14 -0
- package/dist/sanitize/visitors/remove-private.js.map +1 -0
- package/dist/sanitize/visitors/remove-restricted-relations.d.ts +3 -0
- package/dist/sanitize/visitors/remove-restricted-relations.js +88 -0
- package/dist/sanitize/visitors/remove-restricted-relations.js.map +1 -0
- package/dist/sanitize/visitors/restricted-fields.d.ts +3 -0
- package/dist/sanitize/visitors/restricted-fields.js +25 -0
- package/dist/sanitize/visitors/restricted-fields.js.map +1 -0
- package/dist/set-creator-fields.d.ts +9 -0
- package/dist/set-creator-fields.js +39 -0
- package/dist/set-creator-fields.js.map +1 -0
- package/dist/string-formatting.d.ts +15 -0
- package/dist/string-formatting.js +85 -0
- package/dist/string-formatting.js.map +1 -0
- package/dist/template-configuration.d.ts +5 -0
- package/dist/template-configuration.js +30 -0
- package/dist/template-configuration.js.map +1 -0
- package/dist/template.d.ts +9 -0
- package/dist/template.js +20 -0
- package/dist/template.js.map +1 -0
- package/dist/traverse/factory.d.ts +78 -0
- package/dist/traverse/factory.js +127 -0
- package/dist/traverse/factory.js.map +1 -0
- package/dist/traverse/index.d.ts +5 -0
- package/dist/traverse/index.js +17 -0
- package/dist/traverse/index.js.map +1 -0
- package/dist/traverse/query-fields.d.ts +3 -0
- package/dist/traverse/query-fields.js +35 -0
- package/dist/traverse/query-fields.js.map +1 -0
- package/dist/traverse/query-filters.d.ts +3 -0
- package/dist/traverse/query-filters.js +75 -0
- package/dist/traverse/query-filters.js.map +1 -0
- package/dist/traverse/query-populate.d.ts +3 -0
- package/dist/traverse/query-populate.js +144 -0
- package/dist/traverse/query-populate.js.map +1 -0
- package/dist/traverse/query-sort.d.ts +3 -0
- package/dist/traverse/query-sort.js +116 -0
- package/dist/traverse/query-sort.js.map +1 -0
- package/dist/traverse-entity.d.ts +31 -0
- package/dist/traverse-entity.js +134 -0
- package/dist/traverse-entity.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/validators.d.ts +13 -0
- package/dist/validators.js +120 -0
- package/dist/validators.js.map +1 -0
- package/dist/webhook.d.ts +5 -0
- package/dist/webhook.js +27 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +19 -4
- package/.eslintignore +0 -3
- package/.eslintrc.js +0 -4
- package/index.d.ts +0 -5
- package/lib/async.d.ts +0 -21
- package/lib/async.js +0 -45
- package/lib/build-query.js +0 -208
- package/lib/code-generator.js +0 -13
- package/lib/config.js +0 -88
- package/lib/content-types.js +0 -196
- package/lib/convert-query-params.js +0 -586
- package/lib/env-helper.js +0 -98
- package/lib/errors.js +0 -113
- package/lib/file.js +0 -60
- package/lib/format-yup-error.js +0 -20
- package/lib/hooks.js +0 -110
- package/lib/import-default.js +0 -10
- package/lib/index.js +0 -99
- package/lib/object-formatting.js +0 -15
- package/lib/operators.js +0 -74
- package/lib/pagination.js +0 -99
- package/lib/parse-multipart.js +0 -44
- package/lib/parse-type.js +0 -100
- package/lib/policy.js +0 -129
- package/lib/print-value.js +0 -52
- package/lib/provider-factory.js +0 -116
- package/lib/relations.js +0 -31
- package/lib/sanitize/index.js +0 -143
- package/lib/sanitize/sanitizers.js +0 -163
- package/lib/sanitize/visitors/index.js +0 -11
- package/lib/sanitize/visitors/remove-dynamic-zones.js +0 -9
- package/lib/sanitize/visitors/remove-morph-to-relations.js +0 -9
- package/lib/sanitize/visitors/remove-password.js +0 -7
- package/lib/sanitize/visitors/remove-private.js +0 -15
- package/lib/sanitize/visitors/remove-restricted-relations.js +0 -81
- package/lib/sanitize/visitors/restricted-fields.js +0 -32
- package/lib/set-creator-fields.js +0 -17
- package/lib/string-formatting.js +0 -79
- package/lib/template-configuration.js +0 -32
- package/lib/template.js +0 -28
- package/lib/traverse/factory.js +0 -157
- package/lib/traverse/index.js +0 -16
- package/lib/traverse/query-fields.js +0 -39
- package/lib/traverse/query-filters.js +0 -97
- package/lib/traverse/query-populate.js +0 -191
- package/lib/traverse/query-sort.js +0 -171
- package/lib/traverse-entity.js +0 -166
- package/lib/validators.js +0 -120
- package/lib/webhook.js +0 -30
package/lib/parse-type.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
const dates = require('date-fns');
|
|
5
|
-
|
|
6
|
-
const timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;
|
|
7
|
-
|
|
8
|
-
const parseTime = (value) => {
|
|
9
|
-
if (dates.isDate(value)) return dates.format(value, 'HH:mm:ss.SSS');
|
|
10
|
-
|
|
11
|
-
if (typeof value !== 'string') {
|
|
12
|
-
throw new Error(`Expected a string, got a ${typeof value}`);
|
|
13
|
-
}
|
|
14
|
-
const result = value.match(timeRegex);
|
|
15
|
-
|
|
16
|
-
if (result === null) {
|
|
17
|
-
throw new Error('Invalid time format, expected HH:mm:ss.SSS');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const [, hours, minutes, seconds, fraction = '.000'] = result;
|
|
21
|
-
const fractionPart = _.padEnd(fraction.slice(1), 3, '0');
|
|
22
|
-
|
|
23
|
-
return `${hours}:${minutes}:${seconds}.${fractionPart}`;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const parseDate = (value) => {
|
|
27
|
-
if (dates.isDate(value)) return dates.format(value, 'yyyy-MM-dd');
|
|
28
|
-
try {
|
|
29
|
-
const date = dates.parseISO(value);
|
|
30
|
-
|
|
31
|
-
if (dates.isValid(date)) return dates.format(date, 'yyyy-MM-dd');
|
|
32
|
-
|
|
33
|
-
throw new Error(`Invalid format, expected an ISO compatible date`);
|
|
34
|
-
} catch (error) {
|
|
35
|
-
throw new Error(`Invalid format, expected an ISO compatible date`);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const parseDateTimeOrTimestamp = (value) => {
|
|
40
|
-
if (dates.isDate(value)) return value;
|
|
41
|
-
try {
|
|
42
|
-
const date = dates.parseISO(value);
|
|
43
|
-
if (dates.isValid(date)) return date;
|
|
44
|
-
|
|
45
|
-
const milliUnixDate = dates.parse(value, 'T', new Date());
|
|
46
|
-
if (dates.isValid(milliUnixDate)) return milliUnixDate;
|
|
47
|
-
|
|
48
|
-
throw new Error(`Invalid format, expected a timestamp or an ISO date`);
|
|
49
|
-
} catch (error) {
|
|
50
|
-
throw new Error(`Invalid format, expected a timestamp or an ISO date`);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Cast basic values based on attribute type
|
|
56
|
-
* @param {Object} options - Options
|
|
57
|
-
* @param {string} options.type - type of the atribute
|
|
58
|
-
* @param {*} options.value - value tu cast
|
|
59
|
-
*/
|
|
60
|
-
const parseType = ({ type, value, forceCast = false }) => {
|
|
61
|
-
switch (type) {
|
|
62
|
-
case 'boolean': {
|
|
63
|
-
if (typeof value === 'boolean') return value;
|
|
64
|
-
|
|
65
|
-
if (['true', 't', '1', 1].includes(value)) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (['false', 'f', '0', 0].includes(value)) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (forceCast) {
|
|
74
|
-
return Boolean(value);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
throw new Error('Invalid boolean input. Expected "t","1","true","false","0","f"');
|
|
78
|
-
}
|
|
79
|
-
case 'integer':
|
|
80
|
-
case 'biginteger':
|
|
81
|
-
case 'float':
|
|
82
|
-
case 'decimal': {
|
|
83
|
-
return _.toNumber(value);
|
|
84
|
-
}
|
|
85
|
-
case 'time': {
|
|
86
|
-
return parseTime(value);
|
|
87
|
-
}
|
|
88
|
-
case 'date': {
|
|
89
|
-
return parseDate(value);
|
|
90
|
-
}
|
|
91
|
-
case 'timestamp':
|
|
92
|
-
case 'datetime': {
|
|
93
|
-
return parseDateTimeOrTimestamp(value);
|
|
94
|
-
}
|
|
95
|
-
default:
|
|
96
|
-
return value;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
module.exports = parseType;
|
package/lib/policy.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Policies util
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const _ = require('lodash');
|
|
8
|
-
const { eq } = require('lodash/fp');
|
|
9
|
-
|
|
10
|
-
const PLUGIN_PREFIX = 'plugin::';
|
|
11
|
-
const API_PREFIX = 'api::';
|
|
12
|
-
|
|
13
|
-
const parsePolicy = (policy) => {
|
|
14
|
-
if (typeof policy === 'string') {
|
|
15
|
-
return { policyName: policy, config: {} };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const { name, config } = policy;
|
|
19
|
-
return { policyName: name, config };
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const searchLocalPolicy = (policyName, { pluginName, apiName }) => {
|
|
23
|
-
if (pluginName) {
|
|
24
|
-
return strapi.policy(`${PLUGIN_PREFIX}${pluginName}.${policyName}`);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (apiName) {
|
|
28
|
-
return strapi.policy(`${API_PREFIX}${apiName}.${policyName}`);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const globalPolicy = ({ method, endpoint, controller, action, plugin }) => {
|
|
33
|
-
return async (ctx, next) => {
|
|
34
|
-
ctx.request.route = {
|
|
35
|
-
endpoint: `${method} ${endpoint}`,
|
|
36
|
-
controller: _.toLower(controller),
|
|
37
|
-
action: _.toLower(action),
|
|
38
|
-
verb: _.toLower(method),
|
|
39
|
-
plugin,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
await next();
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const resolvePolicies = (config, { pluginName, apiName } = {}) => {
|
|
47
|
-
return config.map((policyConfig) => {
|
|
48
|
-
return {
|
|
49
|
-
handler: getPolicy(policyConfig, { pluginName, apiName }),
|
|
50
|
-
config: policyConfig.config || {},
|
|
51
|
-
};
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const findPolicy = (name, { pluginName, apiName } = {}) => {
|
|
56
|
-
const resolvedPolicy = strapi.policy(name);
|
|
57
|
-
|
|
58
|
-
if (resolvedPolicy !== undefined) {
|
|
59
|
-
return resolvedPolicy;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const localPolicy = searchLocalPolicy(name, { pluginName, apiName });
|
|
63
|
-
|
|
64
|
-
if (localPolicy !== undefined) {
|
|
65
|
-
return localPolicy;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
throw new Error(`Could not find policy "${name}"`);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const getPolicy = (policyConfig, { pluginName, apiName } = {}) => {
|
|
72
|
-
if (typeof policyConfig === 'function') {
|
|
73
|
-
return policyConfig;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const { policyName, config } = parsePolicy(policyConfig);
|
|
77
|
-
|
|
78
|
-
const policy = findPolicy(policyName, { pluginName, apiName });
|
|
79
|
-
|
|
80
|
-
if (typeof policy === 'function') {
|
|
81
|
-
return policy;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (policy.validator) {
|
|
85
|
-
policy.validator(config);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return policy.handler;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const createPolicy = (options) => {
|
|
92
|
-
const { name = 'unnamed', validator, handler } = options;
|
|
93
|
-
|
|
94
|
-
const wrappedValidator = (config) => {
|
|
95
|
-
if (validator) {
|
|
96
|
-
try {
|
|
97
|
-
validator(config);
|
|
98
|
-
} catch (e) {
|
|
99
|
-
throw new Error(`Invalid config passed to "${name}" policy.`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
name,
|
|
106
|
-
validator: wrappedValidator,
|
|
107
|
-
handler,
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const createPolicyContext = (type, ctx) => {
|
|
112
|
-
return Object.assign(
|
|
113
|
-
{
|
|
114
|
-
is: eq(type),
|
|
115
|
-
get type() {
|
|
116
|
-
return type;
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
ctx
|
|
120
|
-
);
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
module.exports = {
|
|
124
|
-
get: getPolicy,
|
|
125
|
-
resolve: resolvePolicies,
|
|
126
|
-
globalPolicy,
|
|
127
|
-
createPolicy,
|
|
128
|
-
createPolicyContext,
|
|
129
|
-
};
|
package/lib/print-value.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Code copied from the yup library (https://github.com/jquense/yup)
|
|
4
|
-
// https://github.com/jquense/yup/blob/2778b88bdacd5260d593c6468793da2e77daf21f/src/util/printValue.ts
|
|
5
|
-
|
|
6
|
-
const { toString } = Object.prototype;
|
|
7
|
-
const errorToString = Error.prototype.toString;
|
|
8
|
-
const regExpToString = RegExp.prototype.toString;
|
|
9
|
-
const symbolToString = typeof Symbol !== 'undefined' ? Symbol.prototype.toString : () => '';
|
|
10
|
-
|
|
11
|
-
const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/;
|
|
12
|
-
|
|
13
|
-
function printNumber(val) {
|
|
14
|
-
// eslint-disable-next-line eqeqeq
|
|
15
|
-
if (val != +val) return 'NaN';
|
|
16
|
-
const isNegativeZero = val === 0 && 1 / val < 0;
|
|
17
|
-
return isNegativeZero ? '-0' : `${val}`;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function printSimpleValue(val, quoteStrings = false) {
|
|
21
|
-
if (val == null || val === true || val === false) return `${val}`;
|
|
22
|
-
|
|
23
|
-
const typeOf = typeof val;
|
|
24
|
-
if (typeOf === 'number') return printNumber(val);
|
|
25
|
-
if (typeOf === 'string') return quoteStrings ? `"${val}"` : val;
|
|
26
|
-
if (typeOf === 'function') return `[Function ${val.name || 'anonymous'}]`;
|
|
27
|
-
if (typeOf === 'symbol') return symbolToString.call(val).replace(SYMBOL_REGEXP, 'Symbol($1)');
|
|
28
|
-
|
|
29
|
-
const tag = toString.call(val).slice(8, -1);
|
|
30
|
-
if (tag === 'Date') return Number.isNaN(val.getTime()) ? `${val}` : val.toISOString(val);
|
|
31
|
-
if (tag === 'Error' || val instanceof Error) return `[${errorToString.call(val)}]`;
|
|
32
|
-
if (tag === 'RegExp') return regExpToString.call(val);
|
|
33
|
-
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function printValue(value, quoteStrings) {
|
|
38
|
-
const result = printSimpleValue(value, quoteStrings);
|
|
39
|
-
if (result !== null) return result;
|
|
40
|
-
|
|
41
|
-
return JSON.stringify(
|
|
42
|
-
value,
|
|
43
|
-
function replacer(key, value) {
|
|
44
|
-
const result = printSimpleValue(this[key], quoteStrings);
|
|
45
|
-
if (result !== null) return result;
|
|
46
|
-
return value;
|
|
47
|
-
},
|
|
48
|
-
2
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
module.exports = printValue;
|
package/lib/provider-factory.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { cloneDeep } = require('lodash/fp');
|
|
4
|
-
const { createAsyncSeriesHook, createAsyncParallelHook } = require('./hooks');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef ProviderHooksMap
|
|
8
|
-
* @property willRegister
|
|
9
|
-
* @property didRegister
|
|
10
|
-
* @property willDelete
|
|
11
|
-
* @property didDelete
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Creates a new object containing various hooks used by the providers
|
|
16
|
-
* @return {ProviderHooksMap}
|
|
17
|
-
*/
|
|
18
|
-
const createProviderHooksMap = () => ({
|
|
19
|
-
// Register events
|
|
20
|
-
willRegister: createAsyncSeriesHook(),
|
|
21
|
-
didRegister: createAsyncParallelHook(),
|
|
22
|
-
// Delete events
|
|
23
|
-
willDelete: createAsyncParallelHook(),
|
|
24
|
-
didDelete: createAsyncParallelHook(),
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* A Provider factory
|
|
29
|
-
* @param {Object} [options] - The factory options
|
|
30
|
-
* @param {boolean = true} options.throwOnDuplicates - Specify the wanted behaviour when encountering a duplicate key on register
|
|
31
|
-
*/
|
|
32
|
-
const providerFactory = (options = {}) => {
|
|
33
|
-
const { throwOnDuplicates = true } = options;
|
|
34
|
-
|
|
35
|
-
const state = {
|
|
36
|
-
hooks: createProviderHooksMap(),
|
|
37
|
-
registry: new Map(),
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
hooks: state.hooks,
|
|
42
|
-
|
|
43
|
-
async register(key, item) {
|
|
44
|
-
if (throwOnDuplicates && this.has(key)) {
|
|
45
|
-
throw new Error(`Duplicated item key: ${key}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
await state.hooks.willRegister.call({ key, value: item });
|
|
49
|
-
|
|
50
|
-
state.registry.set(key, item);
|
|
51
|
-
|
|
52
|
-
await state.hooks.didRegister.call({ key, value: cloneDeep(item) });
|
|
53
|
-
|
|
54
|
-
return this;
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
async delete(key) {
|
|
58
|
-
if (this.has(key)) {
|
|
59
|
-
const item = this.get(key);
|
|
60
|
-
|
|
61
|
-
await state.hooks.willDelete.call({ key, value: cloneDeep(item) });
|
|
62
|
-
|
|
63
|
-
state.registry.delete(key);
|
|
64
|
-
|
|
65
|
-
await state.hooks.didDelete.call({ key, value: cloneDeep(item) });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return this;
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
get(key) {
|
|
72
|
-
return state.registry.get(key);
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
getWhere(filters = {}) {
|
|
76
|
-
const items = this.values();
|
|
77
|
-
const filtersEntries = Object.entries(filters);
|
|
78
|
-
|
|
79
|
-
if (filtersEntries.length === 0) {
|
|
80
|
-
return items;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return items.filter((item) => {
|
|
84
|
-
return filtersEntries.every(([key, value]) => item[key] === value);
|
|
85
|
-
});
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
values() {
|
|
89
|
-
return Array.from(state.registry.values());
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
keys() {
|
|
93
|
-
return Array.from(state.registry.keys());
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
has(key) {
|
|
97
|
-
return state.registry.has(key);
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
size() {
|
|
101
|
-
return state.registry.size;
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
async clear() {
|
|
105
|
-
const keys = this.keys();
|
|
106
|
-
|
|
107
|
-
for (const key of keys) {
|
|
108
|
-
await this.delete(key);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return this;
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
module.exports = providerFactory;
|
package/lib/relations.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { isRelationalAttribute } = require('./content-types');
|
|
4
|
-
|
|
5
|
-
const MANY_RELATIONS = ['oneToMany', 'manyToMany'];
|
|
6
|
-
|
|
7
|
-
const getRelationalFields = (contentType) => {
|
|
8
|
-
return Object.keys(contentType.attributes).filter((attributeName) => {
|
|
9
|
-
return contentType.attributes[attributeName].type === 'relation';
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const isOneToAny = (attribute) =>
|
|
14
|
-
isRelationalAttribute(attribute) && ['oneToOne', 'oneToMany'].includes(attribute.relation);
|
|
15
|
-
const isManyToAny = (attribute) =>
|
|
16
|
-
isRelationalAttribute(attribute) && ['manyToMany', 'manyToOne'].includes(attribute.relation);
|
|
17
|
-
const isAnyToOne = (attribute) =>
|
|
18
|
-
isRelationalAttribute(attribute) && ['oneToOne', 'manyToOne'].includes(attribute.relation);
|
|
19
|
-
const isAnyToMany = (attribute) =>
|
|
20
|
-
isRelationalAttribute(attribute) && ['oneToMany', 'manyToMany'].includes(attribute.relation);
|
|
21
|
-
|
|
22
|
-
module.exports = {
|
|
23
|
-
getRelationalFields,
|
|
24
|
-
isOneToAny,
|
|
25
|
-
isManyToAny,
|
|
26
|
-
isAnyToOne,
|
|
27
|
-
isAnyToMany,
|
|
28
|
-
constants: {
|
|
29
|
-
MANY_RELATIONS,
|
|
30
|
-
},
|
|
31
|
-
};
|
package/lib/sanitize/index.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { isArray, cloneDeep } = require('lodash/fp');
|
|
4
|
-
|
|
5
|
-
const { getNonWritableAttributes } = require('../content-types');
|
|
6
|
-
const { pipeAsync } = require('../async');
|
|
7
|
-
|
|
8
|
-
const visitors = require('./visitors');
|
|
9
|
-
const sanitizers = require('./sanitizers');
|
|
10
|
-
const traverseEntity = require('../traverse-entity');
|
|
11
|
-
|
|
12
|
-
const { traverseQueryFilters, traverseQuerySort, traverseQueryPopulate } = require('../traverse');
|
|
13
|
-
|
|
14
|
-
const createContentAPISanitizers = () => {
|
|
15
|
-
const sanitizeInput = (data, schema, { auth } = {}) => {
|
|
16
|
-
if (isArray(data)) {
|
|
17
|
-
return Promise.all(data.map((entry) => sanitizeInput(entry, schema, { auth })));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const nonWritableAttributes = getNonWritableAttributes(schema);
|
|
21
|
-
|
|
22
|
-
const transforms = [
|
|
23
|
-
// Remove non writable attributes
|
|
24
|
-
traverseEntity(visitors.restrictedFields(nonWritableAttributes), { schema }),
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
if (auth) {
|
|
28
|
-
// Remove restricted relations
|
|
29
|
-
transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Apply sanitizers from registry if exists
|
|
33
|
-
strapi.sanitizers
|
|
34
|
-
.get('content-api.input')
|
|
35
|
-
.forEach((sanitizer) => transforms.push(sanitizer(schema)));
|
|
36
|
-
|
|
37
|
-
return pipeAsync(...transforms)(data);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const sanitizeOutput = async (data, schema, { auth } = {}) => {
|
|
41
|
-
if (isArray(data)) {
|
|
42
|
-
const res = new Array(data.length);
|
|
43
|
-
for (let i = 0; i < data.length; i += 1) {
|
|
44
|
-
res[i] = await sanitizeOutput(data[i], schema, { auth });
|
|
45
|
-
}
|
|
46
|
-
return res;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const transforms = [(data) => sanitizers.defaultSanitizeOutput(schema, data)];
|
|
50
|
-
|
|
51
|
-
if (auth) {
|
|
52
|
-
transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Apply sanitizers from registry if exists
|
|
56
|
-
strapi.sanitizers
|
|
57
|
-
.get('content-api.output')
|
|
58
|
-
.forEach((sanitizer) => transforms.push(sanitizer(schema)));
|
|
59
|
-
|
|
60
|
-
return pipeAsync(...transforms)(data);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const sanitizeQuery = async (query, schema, { auth } = {}) => {
|
|
64
|
-
const { filters, sort, fields, populate } = query;
|
|
65
|
-
|
|
66
|
-
const sanitizedQuery = cloneDeep(query);
|
|
67
|
-
|
|
68
|
-
if (filters) {
|
|
69
|
-
Object.assign(sanitizedQuery, { filters: await sanitizeFilters(filters, schema, { auth }) });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (sort) {
|
|
73
|
-
Object.assign(sanitizedQuery, { sort: await sanitizeSort(sort, schema, { auth }) });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (fields) {
|
|
77
|
-
Object.assign(sanitizedQuery, { fields: await sanitizeFields(fields, schema) });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (populate) {
|
|
81
|
-
Object.assign(sanitizedQuery, { populate: await sanitizePopulate(populate, schema) });
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return sanitizedQuery;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const sanitizeFilters = (filters, schema, { auth } = {}) => {
|
|
88
|
-
if (isArray(filters)) {
|
|
89
|
-
return Promise.all(filters.map((filter) => sanitizeFilters(filter, schema, { auth })));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const transforms = [sanitizers.defaultSanitizeFilters(schema)];
|
|
93
|
-
|
|
94
|
-
if (auth) {
|
|
95
|
-
transforms.push(traverseQueryFilters(visitors.removeRestrictedRelations(auth), { schema }));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return pipeAsync(...transforms)(filters);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const sanitizeSort = (sort, schema, { auth } = {}) => {
|
|
102
|
-
const transforms = [sanitizers.defaultSanitizeSort(schema)];
|
|
103
|
-
|
|
104
|
-
if (auth) {
|
|
105
|
-
transforms.push(traverseQuerySort(visitors.removeRestrictedRelations(auth), { schema }));
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return pipeAsync(...transforms)(sort);
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const sanitizeFields = (fields, schema) => {
|
|
112
|
-
const transforms = [sanitizers.defaultSanitizeFields(schema)];
|
|
113
|
-
|
|
114
|
-
return pipeAsync(...transforms)(fields);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const sanitizePopulate = (populate, schema, { auth } = {}) => {
|
|
118
|
-
const transforms = [sanitizers.defaultSanitizePopulate(schema)];
|
|
119
|
-
|
|
120
|
-
if (auth) {
|
|
121
|
-
transforms.push(traverseQueryPopulate(visitors.removeRestrictedRelations(auth), { schema }));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return pipeAsync(...transforms)(populate);
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
input: sanitizeInput,
|
|
129
|
-
output: sanitizeOutput,
|
|
130
|
-
query: sanitizeQuery,
|
|
131
|
-
filters: sanitizeFilters,
|
|
132
|
-
sort: sanitizeSort,
|
|
133
|
-
fields: sanitizeFields,
|
|
134
|
-
populate: sanitizePopulate,
|
|
135
|
-
};
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
module.exports = {
|
|
139
|
-
contentAPI: createContentAPISanitizers(),
|
|
140
|
-
|
|
141
|
-
sanitizers,
|
|
142
|
-
visitors,
|
|
143
|
-
};
|