@strapi/utils 5.0.0-beta.0 → 5.0.0-beta.10
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 +5 -11
- package/dist/async.d.ts.map +1 -1
- package/dist/content-types.d.ts +16 -6
- package/dist/content-types.d.ts.map +1 -1
- package/dist/convert-query-params.d.ts +12 -9
- package/dist/convert-query-params.d.ts.map +1 -1
- package/dist/file.d.ts +9 -4
- package/dist/file.d.ts.map +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1507 -1354
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1499 -1346
- package/dist/index.mjs.map +1 -1
- package/dist/pagination.d.ts +34 -4
- package/dist/pagination.d.ts.map +1 -1
- package/dist/parse-type.d.ts.map +1 -1
- package/dist/policy.d.ts +1 -27
- package/dist/policy.d.ts.map +1 -1
- package/dist/sanitize/index.d.ts +23 -14
- package/dist/sanitize/index.d.ts.map +1 -1
- package/dist/sanitize/sanitizers.d.ts +10 -6
- package/dist/sanitize/sanitizers.d.ts.map +1 -1
- package/dist/set-creator-fields.d.ts.map +1 -1
- package/dist/traverse/factory.d.ts +5 -4
- package/dist/traverse/factory.d.ts.map +1 -1
- package/dist/traverse/index.d.ts +0 -1
- package/dist/traverse/index.d.ts.map +1 -1
- package/dist/traverse/query-populate.d.ts.map +1 -1
- package/dist/traverse-entity.d.ts +12 -2
- package/dist/traverse-entity.d.ts.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validate/index.d.ts +21 -13
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/utils.d.ts +2 -2
- package/dist/validate/utils.d.ts.map +1 -1
- package/dist/validate/validators.d.ts +9 -5
- package/dist/validate/validators.d.ts.map +1 -1
- package/dist/validate/visitors/index.d.ts +1 -0
- package/dist/validate/visitors/index.d.ts.map +1 -1
- package/dist/validate/visitors/throw-unrecognized-fields.d.ts +4 -0
- package/dist/validate/visitors/throw-unrecognized-fields.d.ts.map +1 -0
- package/dist/validators.d.ts +2 -2
- package/dist/validators.d.ts.map +1 -1
- package/dist/zod.d.ts +3 -0
- package/dist/zod.d.ts.map +1 -0
- package/package.json +11 -9
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import * as _ from "lodash";
|
|
2
|
+
import ___default, { kebabCase } from "lodash";
|
|
3
|
+
import * as dates$1 from "date-fns";
|
|
4
|
+
import { has, union, getOr, assoc, assign, cloneDeep, remove, eq, curry, isObject, isNil, clone, isArray, isEmpty, toPath, defaults, isString, get, toNumber, isInteger, pick, omit, trim, pipe as pipe$1, split, map as map$1, flatten, first, identity, constant, join, merge, trimChars, trimCharsEnd, trimCharsStart, isNumber } from "lodash/fp";
|
|
5
5
|
import { randomUUID } from "crypto";
|
|
6
6
|
import { machineIdSync } from "node-machine-id";
|
|
7
7
|
import * as yup$1 from "yup";
|
|
8
|
+
import { HttpError } from "http-errors";
|
|
9
|
+
import pMap from "p-map";
|
|
8
10
|
import execa from "execa";
|
|
9
11
|
import preferredPM from "preferred-pm";
|
|
10
12
|
import { Writable } from "node:stream";
|
|
11
13
|
import slugify from "@sindresorhus/slugify";
|
|
14
|
+
import { z } from "zod";
|
|
12
15
|
function _mergeNamespaces(n, m) {
|
|
13
16
|
for (var i = 0; i < m.length; i++) {
|
|
14
17
|
const e = m[i];
|
|
@@ -28,8 +31,6 @@ function _mergeNamespaces(n, m) {
|
|
|
28
31
|
}
|
|
29
32
|
return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
|
|
30
33
|
}
|
|
31
|
-
const _ = require("lodash");
|
|
32
|
-
const dates$1 = require("date-fns");
|
|
33
34
|
const timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;
|
|
34
35
|
const isDate = (v) => {
|
|
35
36
|
return dates$1.isDate(v);
|
|
@@ -128,32 +129,32 @@ const parseType = (options) => {
|
|
|
128
129
|
}
|
|
129
130
|
};
|
|
130
131
|
function envFn(key, defaultValue) {
|
|
131
|
-
return
|
|
132
|
+
return ___default.has(process.env, key) ? process.env[key] : defaultValue;
|
|
132
133
|
}
|
|
133
134
|
function getKey(key) {
|
|
134
135
|
return process.env[key] ?? "";
|
|
135
136
|
}
|
|
136
137
|
const utils = {
|
|
137
138
|
int(key, defaultValue) {
|
|
138
|
-
if (!
|
|
139
|
+
if (!___default.has(process.env, key)) {
|
|
139
140
|
return defaultValue;
|
|
140
141
|
}
|
|
141
142
|
return parseInt(getKey(key), 10);
|
|
142
143
|
},
|
|
143
144
|
float(key, defaultValue) {
|
|
144
|
-
if (!
|
|
145
|
+
if (!___default.has(process.env, key)) {
|
|
145
146
|
return defaultValue;
|
|
146
147
|
}
|
|
147
148
|
return parseFloat(getKey(key));
|
|
148
149
|
},
|
|
149
150
|
bool(key, defaultValue) {
|
|
150
|
-
if (!
|
|
151
|
+
if (!___default.has(process.env, key)) {
|
|
151
152
|
return defaultValue;
|
|
152
153
|
}
|
|
153
154
|
return getKey(key) === "true";
|
|
154
155
|
},
|
|
155
156
|
json(key, defaultValue) {
|
|
156
|
-
if (!
|
|
157
|
+
if (!___default.has(process.env, key)) {
|
|
157
158
|
return defaultValue;
|
|
158
159
|
}
|
|
159
160
|
try {
|
|
@@ -166,7 +167,7 @@ const utils = {
|
|
|
166
167
|
}
|
|
167
168
|
},
|
|
168
169
|
array(key, defaultValue) {
|
|
169
|
-
if (!
|
|
170
|
+
if (!___default.has(process.env, key)) {
|
|
170
171
|
return defaultValue;
|
|
171
172
|
}
|
|
172
173
|
let value = getKey(key);
|
|
@@ -174,11 +175,11 @@ const utils = {
|
|
|
174
175
|
value = value.substring(1, value.length - 1);
|
|
175
176
|
}
|
|
176
177
|
return value.split(",").map((v) => {
|
|
177
|
-
return
|
|
178
|
+
return ___default.trim(___default.trim(v, " "), '"');
|
|
178
179
|
});
|
|
179
180
|
},
|
|
180
181
|
date(key, defaultValue) {
|
|
181
|
-
if (!
|
|
182
|
+
if (!___default.has(process.env, key)) {
|
|
182
183
|
return defaultValue;
|
|
183
184
|
}
|
|
184
185
|
return new Date(getKey(key));
|
|
@@ -245,12 +246,12 @@ const getCreatorFields = (model) => {
|
|
|
245
246
|
const getNonWritableAttributes = (model) => {
|
|
246
247
|
if (!model)
|
|
247
248
|
return [];
|
|
248
|
-
const nonWritableAttributes =
|
|
249
|
+
const nonWritableAttributes = ___default.reduce(
|
|
249
250
|
model.attributes,
|
|
250
251
|
(acc, attr, attrName) => attr.writable === false ? acc.concat(attrName) : acc,
|
|
251
252
|
[]
|
|
252
253
|
);
|
|
253
|
-
return
|
|
254
|
+
return ___default.uniq([
|
|
254
255
|
ID_ATTRIBUTE$4,
|
|
255
256
|
DOC_ID_ATTRIBUTE$4,
|
|
256
257
|
...getTimestamps(model),
|
|
@@ -260,28 +261,37 @@ const getNonWritableAttributes = (model) => {
|
|
|
260
261
|
const getWritableAttributes = (model) => {
|
|
261
262
|
if (!model)
|
|
262
263
|
return [];
|
|
263
|
-
return
|
|
264
|
+
return ___default.difference(Object.keys(model.attributes), getNonWritableAttributes(model));
|
|
264
265
|
};
|
|
265
266
|
const isWritableAttribute = (model, attributeName) => {
|
|
266
267
|
return getWritableAttributes(model).includes(attributeName);
|
|
267
268
|
};
|
|
268
269
|
const getNonVisibleAttributes = (model) => {
|
|
269
|
-
const nonVisibleAttributes =
|
|
270
|
+
const nonVisibleAttributes = ___default.reduce(
|
|
270
271
|
model.attributes,
|
|
271
272
|
(acc, attr, attrName) => attr.visible === false ? acc.concat(attrName) : acc,
|
|
272
273
|
[]
|
|
273
274
|
);
|
|
274
|
-
return
|
|
275
|
+
return ___default.uniq([ID_ATTRIBUTE$4, DOC_ID_ATTRIBUTE$4, ...getTimestamps(model), ...nonVisibleAttributes]);
|
|
275
276
|
};
|
|
276
277
|
const getVisibleAttributes = (model) => {
|
|
277
|
-
return
|
|
278
|
+
return ___default.difference(___default.keys(model.attributes), getNonVisibleAttributes(model));
|
|
278
279
|
};
|
|
279
280
|
const isVisibleAttribute = (model, attributeName) => {
|
|
280
281
|
return getVisibleAttributes(model).includes(attributeName);
|
|
281
282
|
};
|
|
282
|
-
const getOptions = (model) =>
|
|
283
|
-
const hasDraftAndPublish = (model) =>
|
|
284
|
-
const isDraft = (data, model) => hasDraftAndPublish(model) &&
|
|
283
|
+
const getOptions = (model) => ___default.assign({ draftAndPublish: false }, ___default.get(model, "options", {}));
|
|
284
|
+
const hasDraftAndPublish = (model) => ___default.get(model, "options.draftAndPublish", false) === true;
|
|
285
|
+
const isDraft = (data, model) => hasDraftAndPublish(model) && ___default.get(data, PUBLISHED_AT_ATTRIBUTE$1) === null;
|
|
286
|
+
const isSchema = (data) => {
|
|
287
|
+
return typeof data === "object" && data !== null && "modelType" in data && typeof data.modelType === "string" && ["component", "contentType"].includes(data.modelType);
|
|
288
|
+
};
|
|
289
|
+
const isComponentSchema = (data) => {
|
|
290
|
+
return isSchema(data) && data.modelType === "component";
|
|
291
|
+
};
|
|
292
|
+
const isContentTypeSchema = (data) => {
|
|
293
|
+
return isSchema(data) && data.modelType === "contentType";
|
|
294
|
+
};
|
|
285
295
|
const isSingleType = ({ kind = COLLECTION_TYPE }) => kind === SINGLE_TYPE;
|
|
286
296
|
const isCollectionType = ({ kind = COLLECTION_TYPE }) => kind === COLLECTION_TYPE;
|
|
287
297
|
const isKind = (kind) => (model) => model.kind === kind;
|
|
@@ -290,9 +300,9 @@ const getStoredPrivateAttributes = (model) => union(
|
|
|
290
300
|
getOr([], "options.privateAttributes", model)
|
|
291
301
|
);
|
|
292
302
|
const getPrivateAttributes = (model) => {
|
|
293
|
-
return
|
|
303
|
+
return ___default.union(
|
|
294
304
|
getStoredPrivateAttributes(model),
|
|
295
|
-
|
|
305
|
+
___default.keys(___default.pickBy(model.attributes, (attr) => !!attr.private))
|
|
296
306
|
);
|
|
297
307
|
};
|
|
298
308
|
const isPrivateAttribute = (model, attributeName) => {
|
|
@@ -302,17 +312,22 @@ const isPrivateAttribute = (model, attributeName) => {
|
|
|
302
312
|
return getStoredPrivateAttributes(model).includes(attributeName);
|
|
303
313
|
};
|
|
304
314
|
const isScalarAttribute = (attribute) => {
|
|
305
|
-
return !["media", "component", "relation", "dynamiczone"].includes(attribute
|
|
315
|
+
return attribute && !["media", "component", "relation", "dynamiczone"].includes(attribute.type);
|
|
316
|
+
};
|
|
317
|
+
const getDoesAttributeRequireValidation = (attribute) => {
|
|
318
|
+
return attribute.required || attribute.unique || Object.prototype.hasOwnProperty.call(attribute, "max") || Object.prototype.hasOwnProperty.call(attribute, "min") || Object.prototype.hasOwnProperty.call(attribute, "maxLength") || Object.prototype.hasOwnProperty.call(attribute, "minLength");
|
|
306
319
|
};
|
|
307
320
|
const isMediaAttribute = (attribute) => attribute?.type === "media";
|
|
308
321
|
const isRelationalAttribute = (attribute) => attribute?.type === "relation";
|
|
322
|
+
const HAS_RELATION_REORDERING = ["manyToMany", "manyToOne", "oneToMany"];
|
|
323
|
+
const hasRelationReordering = (attribute) => isRelationalAttribute(attribute) && HAS_RELATION_REORDERING.includes(attribute.relation);
|
|
309
324
|
const isComponentAttribute = (attribute) => ["component", "dynamiczone"].includes(attribute?.type);
|
|
310
|
-
const isDynamicZoneAttribute = (attribute) => attribute
|
|
325
|
+
const isDynamicZoneAttribute = (attribute) => !!attribute && attribute.type === "dynamiczone";
|
|
311
326
|
const isMorphToRelationalAttribute = (attribute) => {
|
|
312
|
-
return isRelationalAttribute(attribute) && attribute
|
|
327
|
+
return !!attribute && isRelationalAttribute(attribute) && attribute.relation?.startsWith?.("morphTo");
|
|
313
328
|
};
|
|
314
329
|
const getComponentAttributes = (schema) => {
|
|
315
|
-
return
|
|
330
|
+
return ___default.reduce(
|
|
316
331
|
schema.attributes,
|
|
317
332
|
(acc, attr, attrName) => {
|
|
318
333
|
if (isComponentAttribute(attr))
|
|
@@ -323,7 +338,7 @@ const getComponentAttributes = (schema) => {
|
|
|
323
338
|
);
|
|
324
339
|
};
|
|
325
340
|
const getScalarAttributes = (schema) => {
|
|
326
|
-
return
|
|
341
|
+
return ___default.reduce(
|
|
327
342
|
schema.attributes,
|
|
328
343
|
(acc, attr, attrName) => {
|
|
329
344
|
if (isScalarAttribute(attr))
|
|
@@ -333,11 +348,22 @@ const getScalarAttributes = (schema) => {
|
|
|
333
348
|
[]
|
|
334
349
|
);
|
|
335
350
|
};
|
|
351
|
+
const getRelationalAttributes = (schema) => {
|
|
352
|
+
return ___default.reduce(
|
|
353
|
+
schema.attributes,
|
|
354
|
+
(acc, attr, attrName) => {
|
|
355
|
+
if (isRelationalAttribute(attr))
|
|
356
|
+
acc.push(attrName);
|
|
357
|
+
return acc;
|
|
358
|
+
},
|
|
359
|
+
[]
|
|
360
|
+
);
|
|
361
|
+
};
|
|
336
362
|
const isTypedAttribute = (attribute, type) => {
|
|
337
|
-
return
|
|
363
|
+
return ___default.has(attribute, "type") && attribute.type === type;
|
|
338
364
|
};
|
|
339
365
|
const getContentTypeRoutePrefix = (contentType) => {
|
|
340
|
-
return isSingleType(contentType) ?
|
|
366
|
+
return isSingleType(contentType) ? ___default.kebabCase(contentType.info.singularName) : ___default.kebabCase(contentType.info.pluralName);
|
|
341
367
|
};
|
|
342
368
|
const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
343
369
|
__proto__: null,
|
|
@@ -345,17 +371,22 @@ const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
|
|
|
345
371
|
getComponentAttributes,
|
|
346
372
|
getContentTypeRoutePrefix,
|
|
347
373
|
getCreatorFields,
|
|
374
|
+
getDoesAttributeRequireValidation,
|
|
348
375
|
getNonVisibleAttributes,
|
|
349
376
|
getNonWritableAttributes,
|
|
350
377
|
getOptions,
|
|
351
378
|
getPrivateAttributes,
|
|
379
|
+
getRelationalAttributes,
|
|
352
380
|
getScalarAttributes,
|
|
353
381
|
getTimestamps,
|
|
354
382
|
getVisibleAttributes,
|
|
355
383
|
getWritableAttributes,
|
|
356
384
|
hasDraftAndPublish,
|
|
385
|
+
hasRelationReordering,
|
|
357
386
|
isCollectionType,
|
|
358
387
|
isComponentAttribute,
|
|
388
|
+
isComponentSchema,
|
|
389
|
+
isContentTypeSchema,
|
|
359
390
|
isDraft,
|
|
360
391
|
isDynamicZoneAttribute,
|
|
361
392
|
isKind,
|
|
@@ -364,6 +395,7 @@ const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
|
|
|
364
395
|
isPrivateAttribute,
|
|
365
396
|
isRelationalAttribute,
|
|
366
397
|
isScalarAttribute,
|
|
398
|
+
isSchema,
|
|
367
399
|
isSingleType,
|
|
368
400
|
isTypedAttribute,
|
|
369
401
|
isVisibleAttribute,
|
|
@@ -516,201 +548,33 @@ const providerFactory = (options = {}) => {
|
|
|
516
548
|
}
|
|
517
549
|
};
|
|
518
550
|
};
|
|
519
|
-
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
return res;
|
|
551
|
+
const traverseEntity = async (visitor2, options, entity) => {
|
|
552
|
+
const { path = { raw: null, attribute: null }, schema, getModel } = options;
|
|
553
|
+
let parent = options.parent;
|
|
554
|
+
const traverseMorphRelationTarget = async (visitor22, path2, entry) => {
|
|
555
|
+
const targetSchema = getModel(entry.__type);
|
|
556
|
+
const traverseOptions = { schema: targetSchema, path: path2, getModel, parent };
|
|
557
|
+
return traverseEntity(visitor22, traverseOptions, entry);
|
|
527
558
|
};
|
|
528
|
-
|
|
529
|
-
const
|
|
530
|
-
|
|
531
|
-
let acc = initialValue;
|
|
532
|
-
for (let i = 0; i < mixedArray.length; i += 1) {
|
|
533
|
-
acc = await iteratee(acc, await mixedArray[i], i);
|
|
534
|
-
}
|
|
535
|
-
return acc;
|
|
536
|
-
};
|
|
537
|
-
const async = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
538
|
-
__proto__: null,
|
|
539
|
-
map,
|
|
540
|
-
pipe,
|
|
541
|
-
reduce
|
|
542
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
543
|
-
const visitor$8 = ({ key, attribute }, { remove: remove2 }) => {
|
|
544
|
-
if (attribute?.type === "password") {
|
|
545
|
-
remove2(key);
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
const visitor$7 = ({ schema, key, attribute }, { remove: remove2 }) => {
|
|
549
|
-
if (!attribute) {
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
|
|
553
|
-
if (isPrivate) {
|
|
554
|
-
remove2(key);
|
|
555
|
-
}
|
|
556
|
-
};
|
|
557
|
-
const ACTIONS_TO_VERIFY$1 = ["find"];
|
|
558
|
-
const { CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$1 } = constants$1;
|
|
559
|
-
const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schema }, { remove: remove2, set }) => {
|
|
560
|
-
if (!attribute) {
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
const isRelation = attribute.type === "relation";
|
|
564
|
-
if (!isRelation) {
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
const handleMorphRelation = async () => {
|
|
568
|
-
const newMorphValue = [];
|
|
569
|
-
for (const element of data[key]) {
|
|
570
|
-
const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${element.__type}.${action}`);
|
|
571
|
-
const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
|
|
572
|
-
if (isAllowed) {
|
|
573
|
-
newMorphValue.push(element);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
if (newMorphValue.length === 0) {
|
|
577
|
-
remove2(key);
|
|
578
|
-
} else {
|
|
579
|
-
set(key, newMorphValue);
|
|
580
|
-
}
|
|
559
|
+
const traverseRelationTarget = (schema2) => async (visitor22, path2, entry) => {
|
|
560
|
+
const traverseOptions = { schema: schema2, path: path2, getModel, parent };
|
|
561
|
+
return traverseEntity(visitor22, traverseOptions, entry);
|
|
581
562
|
};
|
|
582
|
-
const
|
|
583
|
-
const
|
|
584
|
-
const
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
563
|
+
const traverseMediaTarget = async (visitor22, path2, entry) => {
|
|
564
|
+
const targetSchemaUID = "plugin::upload.file";
|
|
565
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
566
|
+
const traverseOptions = { schema: targetSchema, path: path2, getModel, parent };
|
|
567
|
+
return traverseEntity(visitor22, traverseOptions, entry);
|
|
568
|
+
};
|
|
569
|
+
const traverseComponent = async (visitor22, path2, schema2, entry) => {
|
|
570
|
+
const traverseOptions = { schema: schema2, path: path2, getModel, parent };
|
|
571
|
+
return traverseEntity(visitor22, traverseOptions, entry);
|
|
572
|
+
};
|
|
573
|
+
const visitDynamicZoneEntry = async (visitor22, path2, entry) => {
|
|
574
|
+
const targetSchema = getModel(entry.__component);
|
|
575
|
+
const traverseOptions = { schema: targetSchema, path: path2, getModel, parent };
|
|
576
|
+
return traverseEntity(visitor22, traverseOptions, entry);
|
|
588
577
|
};
|
|
589
|
-
const isCreatorRelation = [CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE$1].includes(key);
|
|
590
|
-
if (isMorphToRelationalAttribute(attribute)) {
|
|
591
|
-
await handleMorphRelation();
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
if (isCreatorRelation && schema.options?.populateCreatorFields) {
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
await handleRegularRelation();
|
|
598
|
-
};
|
|
599
|
-
const hasAccessToSomeScopes$1 = async (scopes, auth) => {
|
|
600
|
-
for (const scope of scopes) {
|
|
601
|
-
try {
|
|
602
|
-
await strapi.auth.verify(auth, { scope });
|
|
603
|
-
return true;
|
|
604
|
-
} catch {
|
|
605
|
-
continue;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
return false;
|
|
609
|
-
};
|
|
610
|
-
const visitor$6 = ({ key, attribute }, { remove: remove2 }) => {
|
|
611
|
-
if (isMorphToRelationalAttribute(attribute)) {
|
|
612
|
-
remove2(key);
|
|
613
|
-
}
|
|
614
|
-
};
|
|
615
|
-
const visitor$5 = ({ key, attribute }, { remove: remove2 }) => {
|
|
616
|
-
if (isDynamicZoneAttribute(attribute)) {
|
|
617
|
-
remove2(key);
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
const removeDisallowedFields = (allowedFields = null) => ({ key, path: { attribute: path } }, { remove: remove2 }) => {
|
|
621
|
-
if (allowedFields === null) {
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
if (!(isArray(allowedFields) && allowedFields.every(isString))) {
|
|
625
|
-
throw new TypeError(
|
|
626
|
-
`Expected array of strings for allowedFields but got "${typeof allowedFields}"`
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
|
-
if (isNil(path)) {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
const containedPaths = getContainedPaths$1(path);
|
|
633
|
-
const isPathAllowed = allowedFields.some(
|
|
634
|
-
(p) => containedPaths.includes(p) || p.startsWith(`${path}.`)
|
|
635
|
-
);
|
|
636
|
-
if (isPathAllowed) {
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
remove2(key);
|
|
640
|
-
};
|
|
641
|
-
const getContainedPaths$1 = (path) => {
|
|
642
|
-
const parts = toPath(path);
|
|
643
|
-
return parts.reduce((acc, value, index2, list) => {
|
|
644
|
-
return [...acc, list.slice(0, index2 + 1).join(".")];
|
|
645
|
-
}, []);
|
|
646
|
-
};
|
|
647
|
-
const removeRestrictedFields = (restrictedFields = null) => ({ key, path: { attribute: path } }, { remove: remove2 }) => {
|
|
648
|
-
if (restrictedFields === null) {
|
|
649
|
-
remove2(key);
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {
|
|
653
|
-
throw new TypeError(
|
|
654
|
-
`Expected array of strings for restrictedFields but got "${typeof restrictedFields}"`
|
|
655
|
-
);
|
|
656
|
-
}
|
|
657
|
-
if (restrictedFields.includes(path)) {
|
|
658
|
-
remove2(key);
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
|
-
const isRestrictedNested = restrictedFields.some(
|
|
662
|
-
(allowedPath) => path?.toString().startsWith(`${allowedPath}.`)
|
|
663
|
-
);
|
|
664
|
-
if (isRestrictedNested) {
|
|
665
|
-
remove2(key);
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
const visitor$4 = ({ schema, key, value }, { set }) => {
|
|
669
|
-
if (key === "" && value === "*") {
|
|
670
|
-
const { attributes } = schema;
|
|
671
|
-
const newPopulateQuery = Object.entries(attributes).filter(
|
|
672
|
-
([, attribute]) => ["relation", "component", "media", "dynamiczone"].includes(attribute.type)
|
|
673
|
-
).reduce((acc, [key2]) => ({ ...acc, [key2]: true }), {});
|
|
674
|
-
set("", newPopulateQuery);
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
const visitors$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
678
|
-
__proto__: null,
|
|
679
|
-
expandWildcardPopulate: visitor$4,
|
|
680
|
-
removeDisallowedFields,
|
|
681
|
-
removeDynamicZones: visitor$5,
|
|
682
|
-
removeMorphToRelations: visitor$6,
|
|
683
|
-
removePassword: visitor$8,
|
|
684
|
-
removePrivate: visitor$7,
|
|
685
|
-
removeRestrictedFields,
|
|
686
|
-
removeRestrictedRelations
|
|
687
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
688
|
-
const traverseMorphRelationTarget = async (visitor2, path, entry) => {
|
|
689
|
-
const targetSchema = strapi.getModel(entry.__type);
|
|
690
|
-
const traverseOptions = { schema: targetSchema, path };
|
|
691
|
-
return traverseEntity(visitor2, traverseOptions, entry);
|
|
692
|
-
};
|
|
693
|
-
const traverseRelationTarget = (schema) => async (visitor2, path, entry) => {
|
|
694
|
-
const traverseOptions = { schema, path };
|
|
695
|
-
return traverseEntity(visitor2, traverseOptions, entry);
|
|
696
|
-
};
|
|
697
|
-
const traverseMediaTarget = async (visitor2, path, entry) => {
|
|
698
|
-
const targetSchemaUID = "plugin::upload.file";
|
|
699
|
-
const targetSchema = strapi.getModel(targetSchemaUID);
|
|
700
|
-
const traverseOptions = { schema: targetSchema, path };
|
|
701
|
-
return traverseEntity(visitor2, traverseOptions, entry);
|
|
702
|
-
};
|
|
703
|
-
const traverseComponent = async (visitor2, path, schema, entry) => {
|
|
704
|
-
const traverseOptions = { schema, path };
|
|
705
|
-
return traverseEntity(visitor2, traverseOptions, entry);
|
|
706
|
-
};
|
|
707
|
-
const visitDynamicZoneEntry = async (visitor2, path, entry) => {
|
|
708
|
-
const targetSchema = strapi.getModel(entry.__component);
|
|
709
|
-
const traverseOptions = { schema: targetSchema, path };
|
|
710
|
-
return traverseEntity(visitor2, traverseOptions, entry);
|
|
711
|
-
};
|
|
712
|
-
const traverseEntity = async (visitor2, options, entity) => {
|
|
713
|
-
const { path = { raw: null, attribute: null }, schema } = options;
|
|
714
578
|
if (!isObject(entity) || isNil(schema)) {
|
|
715
579
|
return entity;
|
|
716
580
|
}
|
|
@@ -720,9 +584,6 @@ const traverseEntity = async (visitor2, options, entity) => {
|
|
|
720
584
|
for (let i = 0; i < keys.length; i += 1) {
|
|
721
585
|
const key = keys[i];
|
|
722
586
|
const attribute = schema.attributes[key];
|
|
723
|
-
if (isNil(attribute)) {
|
|
724
|
-
continue;
|
|
725
|
-
}
|
|
726
587
|
const newPath = { ...path };
|
|
727
588
|
newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;
|
|
728
589
|
if (!isNil(attribute)) {
|
|
@@ -734,16 +595,19 @@ const traverseEntity = async (visitor2, options, entity) => {
|
|
|
734
595
|
key,
|
|
735
596
|
value: copy[key],
|
|
736
597
|
attribute,
|
|
737
|
-
path: newPath
|
|
598
|
+
path: newPath,
|
|
599
|
+
getModel,
|
|
600
|
+
parent
|
|
738
601
|
};
|
|
739
602
|
await visitor2(visitorOptions, visitorUtils);
|
|
740
603
|
const value = copy[key];
|
|
741
|
-
if (isNil(value)) {
|
|
604
|
+
if (isNil(value) || isNil(attribute)) {
|
|
742
605
|
continue;
|
|
743
606
|
}
|
|
607
|
+
parent = { schema, key, attribute, path: newPath };
|
|
744
608
|
if (isRelationalAttribute(attribute)) {
|
|
745
609
|
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
|
746
|
-
const method = isMorphRelation ? traverseMorphRelationTarget : traverseRelationTarget(
|
|
610
|
+
const method = isMorphRelation ? traverseMorphRelationTarget : traverseRelationTarget(getModel(attribute.target));
|
|
747
611
|
if (isArray(value)) {
|
|
748
612
|
const res = new Array(value.length);
|
|
749
613
|
for (let i2 = 0; i2 < value.length; i2 += 1) {
|
|
@@ -768,7 +632,7 @@ const traverseEntity = async (visitor2, options, entity) => {
|
|
|
768
632
|
continue;
|
|
769
633
|
}
|
|
770
634
|
if (attribute.type === "component") {
|
|
771
|
-
const targetSchema =
|
|
635
|
+
const targetSchema = getModel(attribute.component);
|
|
772
636
|
if (isArray(value)) {
|
|
773
637
|
const res = new Array(value.length);
|
|
774
638
|
for (let i2 = 0; i2 < value.length; i2 += 1) {
|
|
@@ -800,74 +664,859 @@ const createVisitorUtils = ({ data }) => ({
|
|
|
800
664
|
}
|
|
801
665
|
});
|
|
802
666
|
const traverseEntity$1 = curry(traverseEntity);
|
|
803
|
-
|
|
804
|
-
const
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
667
|
+
function importDefault(modName) {
|
|
668
|
+
const mod = require(modName);
|
|
669
|
+
return mod && mod.__esModule ? mod.default : mod;
|
|
670
|
+
}
|
|
671
|
+
const machineId = () => {
|
|
672
|
+
try {
|
|
673
|
+
const deviceId = machineIdSync();
|
|
674
|
+
return deviceId;
|
|
675
|
+
} catch (error) {
|
|
676
|
+
const deviceId = randomUUID();
|
|
677
|
+
return deviceId;
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
const formatYupInnerError = (yupError) => ({
|
|
681
|
+
path: toPath(yupError.path),
|
|
682
|
+
message: yupError.message,
|
|
683
|
+
name: yupError.name
|
|
684
|
+
});
|
|
685
|
+
const formatYupErrors = (yupError) => ({
|
|
686
|
+
errors: isEmpty(yupError.inner) ? [formatYupInnerError(yupError)] : yupError.inner.map(formatYupInnerError),
|
|
687
|
+
message: yupError.message
|
|
688
|
+
});
|
|
689
|
+
class ApplicationError extends Error {
|
|
690
|
+
name;
|
|
691
|
+
details;
|
|
692
|
+
message;
|
|
693
|
+
constructor(message = "An application error occured", details = {}) {
|
|
694
|
+
super();
|
|
695
|
+
this.name = "ApplicationError";
|
|
696
|
+
this.message = message;
|
|
697
|
+
this.details = details;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
class ValidationError extends ApplicationError {
|
|
701
|
+
constructor(message, details) {
|
|
702
|
+
super(message, details);
|
|
703
|
+
this.name = "ValidationError";
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
class YupValidationError extends ValidationError {
|
|
707
|
+
constructor(yupError, message) {
|
|
708
|
+
super("Validation");
|
|
709
|
+
const { errors: errors2, message: yupMessage } = formatYupErrors(yupError);
|
|
710
|
+
this.message = message || yupMessage;
|
|
711
|
+
this.details = { errors: errors2 };
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
class PaginationError extends ApplicationError {
|
|
715
|
+
constructor(message = "Invalid pagination", details) {
|
|
716
|
+
super(message, details);
|
|
717
|
+
this.name = "PaginationError";
|
|
718
|
+
this.message = message;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
class NotFoundError extends ApplicationError {
|
|
722
|
+
constructor(message = "Entity not found", details) {
|
|
723
|
+
super(message, details);
|
|
724
|
+
this.name = "NotFoundError";
|
|
725
|
+
this.message = message;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
class ForbiddenError extends ApplicationError {
|
|
729
|
+
constructor(message = "Forbidden access", details) {
|
|
730
|
+
super(message, details);
|
|
731
|
+
this.name = "ForbiddenError";
|
|
732
|
+
this.message = message;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
class UnauthorizedError extends ApplicationError {
|
|
736
|
+
constructor(message = "Unauthorized", details) {
|
|
737
|
+
super(message, details);
|
|
738
|
+
this.name = "UnauthorizedError";
|
|
739
|
+
this.message = message;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
class RateLimitError extends ApplicationError {
|
|
743
|
+
constructor(message = "Too many requests, please try again later.", details) {
|
|
744
|
+
super(message, details);
|
|
745
|
+
this.name = "RateLimitError";
|
|
746
|
+
this.message = message;
|
|
747
|
+
this.details = details || {};
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
class PayloadTooLargeError extends ApplicationError {
|
|
751
|
+
constructor(message = "Entity too large", details) {
|
|
752
|
+
super(message, details);
|
|
753
|
+
this.name = "PayloadTooLargeError";
|
|
754
|
+
this.message = message;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
class PolicyError extends ForbiddenError {
|
|
758
|
+
constructor(message = "Policy Failed", details) {
|
|
759
|
+
super(message, details);
|
|
760
|
+
this.name = "PolicyError";
|
|
761
|
+
this.message = message;
|
|
762
|
+
this.details = details || {};
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
class NotImplementedError extends ApplicationError {
|
|
766
|
+
constructor(message = "This feature is not implemented yet", details) {
|
|
767
|
+
super(message, details);
|
|
768
|
+
this.name = "NotImplementedError";
|
|
769
|
+
this.message = message;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
const errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
773
|
+
__proto__: null,
|
|
774
|
+
ApplicationError,
|
|
775
|
+
ForbiddenError,
|
|
776
|
+
HttpError,
|
|
777
|
+
NotFoundError,
|
|
778
|
+
NotImplementedError,
|
|
779
|
+
PaginationError,
|
|
780
|
+
PayloadTooLargeError,
|
|
781
|
+
PolicyError,
|
|
782
|
+
RateLimitError,
|
|
783
|
+
UnauthorizedError,
|
|
784
|
+
ValidationError,
|
|
785
|
+
YupValidationError
|
|
786
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
787
|
+
const handleYupError = (error, errorMessage) => {
|
|
788
|
+
throw new YupValidationError(error, errorMessage);
|
|
789
|
+
};
|
|
790
|
+
const defaultValidationParam = { strict: true, abortEarly: false };
|
|
791
|
+
const validateYupSchema = (schema, options = {}) => async (body, errorMessage) => {
|
|
792
|
+
try {
|
|
793
|
+
const optionsWithDefaults = defaults(defaultValidationParam, options);
|
|
794
|
+
const result = await schema.validate(body, optionsWithDefaults);
|
|
795
|
+
return result;
|
|
796
|
+
} catch (e) {
|
|
797
|
+
if (e instanceof yup$1.ValidationError) {
|
|
798
|
+
handleYupError(e, errorMessage);
|
|
799
|
+
}
|
|
800
|
+
throw e;
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
const validateYupSchemaSync = (schema, options = {}) => (body, errorMessage) => {
|
|
804
|
+
try {
|
|
805
|
+
const optionsWithDefaults = defaults(defaultValidationParam, options);
|
|
806
|
+
return schema.validateSync(body, optionsWithDefaults);
|
|
807
|
+
} catch (e) {
|
|
808
|
+
if (e instanceof yup$1.ValidationError) {
|
|
809
|
+
handleYupError(e, errorMessage);
|
|
810
|
+
}
|
|
811
|
+
throw e;
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
const GROUP_OPERATORS = ["$and", "$or"];
|
|
815
|
+
const WHERE_OPERATORS = [
|
|
816
|
+
"$not",
|
|
817
|
+
"$in",
|
|
818
|
+
"$notIn",
|
|
819
|
+
"$eq",
|
|
820
|
+
"$eqi",
|
|
821
|
+
"$ne",
|
|
822
|
+
"$nei",
|
|
823
|
+
"$gt",
|
|
824
|
+
"$gte",
|
|
825
|
+
"$lt",
|
|
826
|
+
"$lte",
|
|
827
|
+
"$null",
|
|
828
|
+
"$notNull",
|
|
829
|
+
"$between",
|
|
830
|
+
"$startsWith",
|
|
831
|
+
"$endsWith",
|
|
832
|
+
"$startsWithi",
|
|
833
|
+
"$endsWithi",
|
|
834
|
+
"$contains",
|
|
835
|
+
"$notContains",
|
|
836
|
+
"$containsi",
|
|
837
|
+
"$notContainsi",
|
|
838
|
+
// Experimental, only for internal use
|
|
839
|
+
"$jsonSupersetOf"
|
|
840
|
+
];
|
|
841
|
+
const CAST_OPERATORS = [
|
|
842
|
+
"$not",
|
|
843
|
+
"$in",
|
|
844
|
+
"$notIn",
|
|
845
|
+
"$eq",
|
|
846
|
+
"$ne",
|
|
847
|
+
"$gt",
|
|
848
|
+
"$gte",
|
|
849
|
+
"$lt",
|
|
850
|
+
"$lte",
|
|
851
|
+
"$between"
|
|
852
|
+
];
|
|
853
|
+
const ARRAY_OPERATORS = ["$in", "$notIn", "$between"];
|
|
854
|
+
const OPERATORS = {
|
|
855
|
+
where: WHERE_OPERATORS,
|
|
856
|
+
cast: CAST_OPERATORS,
|
|
857
|
+
group: GROUP_OPERATORS,
|
|
858
|
+
array: ARRAY_OPERATORS
|
|
859
|
+
};
|
|
860
|
+
const OPERATORS_LOWERCASE = Object.fromEntries(
|
|
861
|
+
Object.entries(OPERATORS).map(([key, values]) => [
|
|
862
|
+
key,
|
|
863
|
+
values.map((value) => value.toLowerCase())
|
|
864
|
+
])
|
|
865
|
+
);
|
|
866
|
+
const isObjKey = (key, obj) => {
|
|
867
|
+
return key in obj;
|
|
868
|
+
};
|
|
869
|
+
const isOperatorOfType = (type, key, ignoreCase = false) => {
|
|
870
|
+
if (ignoreCase) {
|
|
871
|
+
return OPERATORS_LOWERCASE[type]?.includes(key.toLowerCase()) ?? false;
|
|
872
|
+
}
|
|
873
|
+
if (isObjKey(type, OPERATORS)) {
|
|
874
|
+
return OPERATORS[type]?.includes(key) ?? false;
|
|
875
|
+
}
|
|
876
|
+
return false;
|
|
877
|
+
};
|
|
878
|
+
const isOperator = (key, ignoreCase = false) => {
|
|
879
|
+
return Object.keys(OPERATORS).some((type) => isOperatorOfType(type, key, ignoreCase));
|
|
880
|
+
};
|
|
881
|
+
const { ID_ATTRIBUTE: ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$3, PUBLISHED_AT_ATTRIBUTE } = constants$1;
|
|
882
|
+
class InvalidOrderError extends Error {
|
|
883
|
+
constructor() {
|
|
884
|
+
super();
|
|
885
|
+
this.message = "Invalid order. order can only be one of asc|desc|ASC|DESC";
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
class InvalidSortError extends Error {
|
|
889
|
+
constructor() {
|
|
890
|
+
super();
|
|
891
|
+
this.message = "Invalid sort parameter. Expected a string, an array of strings, a sort object or an array of sort objects";
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
function validateOrder(order) {
|
|
895
|
+
if (!isString(order) || !["asc", "desc"].includes(order.toLocaleLowerCase())) {
|
|
896
|
+
throw new InvalidOrderError();
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
const convertCountQueryParams = (countQuery) => {
|
|
900
|
+
return parseType({ type: "boolean", value: countQuery });
|
|
901
|
+
};
|
|
902
|
+
const convertOrderingQueryParams = (ordering) => {
|
|
903
|
+
return ordering;
|
|
904
|
+
};
|
|
905
|
+
const isPlainObject = (value) => ___default.isPlainObject(value);
|
|
906
|
+
const isStringArray$3 = (value) => isArray(value) && value.every(isString);
|
|
907
|
+
const createTransformer = ({ getModel }) => {
|
|
908
|
+
const convertSortQueryParams = (sortQuery) => {
|
|
909
|
+
if (typeof sortQuery === "string") {
|
|
910
|
+
return convertStringSortQueryParam(sortQuery);
|
|
911
|
+
}
|
|
912
|
+
if (isStringArray$3(sortQuery)) {
|
|
913
|
+
return sortQuery.flatMap((sortValue) => convertStringSortQueryParam(sortValue));
|
|
914
|
+
}
|
|
915
|
+
if (Array.isArray(sortQuery)) {
|
|
916
|
+
return sortQuery.map((sortValue) => convertNestedSortQueryParam(sortValue));
|
|
917
|
+
}
|
|
918
|
+
if (isPlainObject(sortQuery)) {
|
|
919
|
+
return convertNestedSortQueryParam(sortQuery);
|
|
920
|
+
}
|
|
921
|
+
throw new InvalidSortError();
|
|
922
|
+
};
|
|
923
|
+
const convertStringSortQueryParam = (sortQuery) => {
|
|
924
|
+
return sortQuery.split(",").map((value) => convertSingleSortQueryParam(value));
|
|
925
|
+
};
|
|
926
|
+
const convertSingleSortQueryParam = (sortQuery) => {
|
|
927
|
+
if (!sortQuery) {
|
|
928
|
+
return {};
|
|
929
|
+
}
|
|
930
|
+
if (!isString(sortQuery)) {
|
|
931
|
+
throw new Error("Invalid sort query");
|
|
932
|
+
}
|
|
933
|
+
const [field, order = "asc"] = sortQuery.split(":");
|
|
934
|
+
if (field.length === 0) {
|
|
935
|
+
throw new Error("Field cannot be empty");
|
|
936
|
+
}
|
|
937
|
+
validateOrder(order);
|
|
938
|
+
return ___default.set({}, field, order);
|
|
939
|
+
};
|
|
940
|
+
const convertNestedSortQueryParam = (sortQuery) => {
|
|
941
|
+
const transformedSort = {};
|
|
942
|
+
for (const field of Object.keys(sortQuery)) {
|
|
943
|
+
const order = sortQuery[field];
|
|
944
|
+
if (isPlainObject(order)) {
|
|
945
|
+
transformedSort[field] = convertNestedSortQueryParam(order);
|
|
946
|
+
} else if (typeof order === "string") {
|
|
947
|
+
validateOrder(order);
|
|
948
|
+
transformedSort[field] = order;
|
|
949
|
+
} else {
|
|
950
|
+
throw Error(`Invalid sort type expected object or string got ${typeof order}`);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return transformedSort;
|
|
954
|
+
};
|
|
955
|
+
const convertStartQueryParams = (startQuery) => {
|
|
956
|
+
const startAsANumber = ___default.toNumber(startQuery);
|
|
957
|
+
if (!___default.isInteger(startAsANumber) || startAsANumber < 0) {
|
|
958
|
+
throw new Error(`convertStartQueryParams expected a positive integer got ${startAsANumber}`);
|
|
959
|
+
}
|
|
960
|
+
return startAsANumber;
|
|
961
|
+
};
|
|
962
|
+
const convertLimitQueryParams = (limitQuery) => {
|
|
963
|
+
const limitAsANumber = ___default.toNumber(limitQuery);
|
|
964
|
+
if (!___default.isInteger(limitAsANumber) || limitAsANumber !== -1 && limitAsANumber < 0) {
|
|
965
|
+
throw new Error(`convertLimitQueryParams expected a positive integer got ${limitAsANumber}`);
|
|
966
|
+
}
|
|
967
|
+
if (limitAsANumber === -1) {
|
|
968
|
+
return void 0;
|
|
969
|
+
}
|
|
970
|
+
return limitAsANumber;
|
|
971
|
+
};
|
|
972
|
+
const convertPageQueryParams = (page) => {
|
|
973
|
+
const pageVal = toNumber(page);
|
|
974
|
+
if (!isInteger(pageVal) || pageVal <= 0) {
|
|
975
|
+
throw new PaginationError(
|
|
976
|
+
`Invalid 'page' parameter. Expected an integer > 0, received: ${page}`
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
return pageVal;
|
|
980
|
+
};
|
|
981
|
+
const convertPageSizeQueryParams = (pageSize, page) => {
|
|
982
|
+
const pageSizeVal = toNumber(pageSize);
|
|
983
|
+
if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {
|
|
984
|
+
throw new PaginationError(
|
|
985
|
+
`Invalid 'pageSize' parameter. Expected an integer > 0, received: ${page}`
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
return pageSizeVal;
|
|
989
|
+
};
|
|
990
|
+
const validatePaginationParams = (page, pageSize, start, limit) => {
|
|
991
|
+
const isPagePagination = !isNil(page) || !isNil(pageSize);
|
|
992
|
+
const isOffsetPagination = !isNil(start) || !isNil(limit);
|
|
993
|
+
if (isPagePagination && isOffsetPagination) {
|
|
994
|
+
throw new PaginationError(
|
|
995
|
+
"Invalid pagination attributes. You cannot use page and offset pagination in the same query"
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
class InvalidPopulateError extends Error {
|
|
1000
|
+
constructor() {
|
|
1001
|
+
super();
|
|
1002
|
+
this.message = "Invalid populate parameter. Expected a string, an array of strings, a populate object";
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
const convertPopulateQueryParams = (populate2, schema, depth = 0) => {
|
|
1006
|
+
if (depth === 0 && populate2 === "*") {
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
1009
|
+
if (typeof populate2 === "string") {
|
|
1010
|
+
return populate2.split(",").map((value) => ___default.trim(value));
|
|
1011
|
+
}
|
|
1012
|
+
if (Array.isArray(populate2)) {
|
|
1013
|
+
return ___default.uniq(
|
|
1014
|
+
populate2.flatMap((value) => {
|
|
1015
|
+
if (typeof value !== "string") {
|
|
1016
|
+
throw new InvalidPopulateError();
|
|
1017
|
+
}
|
|
1018
|
+
return value.split(",").map((value2) => ___default.trim(value2));
|
|
1019
|
+
})
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
if (___default.isPlainObject(populate2)) {
|
|
1023
|
+
return convertPopulateObject(populate2, schema);
|
|
1024
|
+
}
|
|
1025
|
+
throw new InvalidPopulateError();
|
|
1026
|
+
};
|
|
1027
|
+
const hasPopulateFragmentDefined = (populate2) => {
|
|
1028
|
+
return typeof populate2 === "object" && "on" in populate2 && !isNil(populate2.on);
|
|
1029
|
+
};
|
|
1030
|
+
const hasCountDefined = (populate2) => {
|
|
1031
|
+
return typeof populate2 === "object" && "count" in populate2 && typeof populate2.count === "boolean";
|
|
1032
|
+
};
|
|
1033
|
+
const convertPopulateObject = (populate2, schema) => {
|
|
1034
|
+
if (!schema) {
|
|
1035
|
+
return {};
|
|
1036
|
+
}
|
|
1037
|
+
const { attributes } = schema;
|
|
1038
|
+
return Object.entries(populate2).reduce((acc, [key, subPopulate]) => {
|
|
1039
|
+
if (___default.isString(subPopulate)) {
|
|
1040
|
+
try {
|
|
1041
|
+
const subPopulateAsBoolean = parseType({ type: "boolean", value: subPopulate });
|
|
1042
|
+
return subPopulateAsBoolean === true ? { ...acc, [key]: true } : acc;
|
|
1043
|
+
} catch {
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
if (___default.isBoolean(subPopulate)) {
|
|
1047
|
+
return subPopulate === true ? { ...acc, [key]: true } : acc;
|
|
1048
|
+
}
|
|
1049
|
+
const attribute = attributes[key];
|
|
1050
|
+
if (!attribute) {
|
|
1051
|
+
return acc;
|
|
1052
|
+
}
|
|
1053
|
+
const isMorphLikeRelationalAttribute = isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);
|
|
1054
|
+
if (isMorphLikeRelationalAttribute) {
|
|
1055
|
+
const hasInvalidProperties = Object.keys(subPopulate).some(
|
|
1056
|
+
(key2) => !["on", "count"].includes(key2)
|
|
1057
|
+
);
|
|
1058
|
+
if (hasInvalidProperties) {
|
|
1059
|
+
throw new Error(
|
|
1060
|
+
`Invalid nested populate for ${schema.info?.singularName}.${key} (${schema.uid}). Expected a fragment ("on") or "count" but found ${JSON.stringify(subPopulate)}`
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
const newSubPopulate = {};
|
|
1064
|
+
if (hasPopulateFragmentDefined(subPopulate)) {
|
|
1065
|
+
Object.assign(newSubPopulate, {
|
|
1066
|
+
on: Object.entries(subPopulate.on).reduce(
|
|
1067
|
+
(acc2, [type, typeSubPopulate]) => ({
|
|
1068
|
+
...acc2,
|
|
1069
|
+
[type]: convertNestedPopulate(typeSubPopulate, getModel(type))
|
|
1070
|
+
}),
|
|
1071
|
+
{}
|
|
1072
|
+
)
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
if (hasCountDefined(subPopulate)) {
|
|
1076
|
+
Object.assign(newSubPopulate, { count: subPopulate.count });
|
|
1077
|
+
}
|
|
1078
|
+
return { ...acc, [key]: newSubPopulate };
|
|
1079
|
+
}
|
|
1080
|
+
if (!isMorphLikeRelationalAttribute && hasPopulateFragmentDefined(subPopulate)) {
|
|
1081
|
+
throw new Error(`Using fragments is not permitted to populate "${key}" in "${schema.uid}"`);
|
|
1082
|
+
}
|
|
1083
|
+
let targetSchemaUID;
|
|
1084
|
+
if (attribute.type === "relation") {
|
|
1085
|
+
targetSchemaUID = attribute.target;
|
|
1086
|
+
} else if (attribute.type === "component") {
|
|
1087
|
+
targetSchemaUID = attribute.component;
|
|
1088
|
+
} else if (attribute.type === "media") {
|
|
1089
|
+
targetSchemaUID = "plugin::upload.file";
|
|
1090
|
+
} else {
|
|
1091
|
+
return acc;
|
|
1092
|
+
}
|
|
1093
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1094
|
+
if (!targetSchema) {
|
|
1095
|
+
return acc;
|
|
1096
|
+
}
|
|
1097
|
+
const populateObject = convertNestedPopulate(subPopulate, targetSchema);
|
|
1098
|
+
if (!populateObject) {
|
|
1099
|
+
return acc;
|
|
1100
|
+
}
|
|
1101
|
+
return {
|
|
1102
|
+
...acc,
|
|
1103
|
+
[key]: populateObject
|
|
1104
|
+
};
|
|
1105
|
+
}, {});
|
|
1106
|
+
};
|
|
1107
|
+
const convertNestedPopulate = (subPopulate, schema) => {
|
|
1108
|
+
if (___default.isString(subPopulate)) {
|
|
1109
|
+
return parseType({ type: "boolean", value: subPopulate, forceCast: true });
|
|
1110
|
+
}
|
|
1111
|
+
if (___default.isBoolean(subPopulate)) {
|
|
1112
|
+
return subPopulate;
|
|
1113
|
+
}
|
|
1114
|
+
if (!isPlainObject(subPopulate)) {
|
|
1115
|
+
throw new Error(`Invalid nested populate. Expected '*' or an object`);
|
|
1116
|
+
}
|
|
1117
|
+
const { sort: sort2, filters: filters2, fields: fields2, populate: populate2, count, ordering, page, pageSize, start, limit } = subPopulate;
|
|
1118
|
+
const query = {};
|
|
1119
|
+
if (sort2) {
|
|
1120
|
+
query.orderBy = convertSortQueryParams(sort2);
|
|
1121
|
+
}
|
|
1122
|
+
if (filters2) {
|
|
1123
|
+
query.where = convertFiltersQueryParams(filters2, schema);
|
|
1124
|
+
}
|
|
1125
|
+
if (fields2) {
|
|
1126
|
+
query.select = convertFieldsQueryParams(fields2);
|
|
1127
|
+
}
|
|
1128
|
+
if (populate2) {
|
|
1129
|
+
query.populate = convertPopulateQueryParams(populate2, schema);
|
|
1130
|
+
}
|
|
1131
|
+
if (count) {
|
|
1132
|
+
query.count = convertCountQueryParams(count);
|
|
1133
|
+
}
|
|
1134
|
+
if (ordering) {
|
|
1135
|
+
query.ordering = convertOrderingQueryParams(ordering);
|
|
1136
|
+
}
|
|
1137
|
+
validatePaginationParams(page, pageSize, start, limit);
|
|
1138
|
+
if (!isNil(page)) {
|
|
1139
|
+
query.page = convertPageQueryParams(page);
|
|
1140
|
+
}
|
|
1141
|
+
if (!isNil(pageSize)) {
|
|
1142
|
+
query.pageSize = convertPageSizeQueryParams(pageSize, page);
|
|
1143
|
+
}
|
|
1144
|
+
if (!isNil(start)) {
|
|
1145
|
+
query.offset = convertStartQueryParams(start);
|
|
1146
|
+
}
|
|
1147
|
+
if (!isNil(limit)) {
|
|
1148
|
+
query.limit = convertLimitQueryParams(limit);
|
|
1149
|
+
}
|
|
1150
|
+
return query;
|
|
1151
|
+
};
|
|
1152
|
+
const convertFieldsQueryParams = (fields2, depth = 0) => {
|
|
1153
|
+
if (depth === 0 && fields2 === "*") {
|
|
1154
|
+
return void 0;
|
|
1155
|
+
}
|
|
1156
|
+
if (typeof fields2 === "string") {
|
|
1157
|
+
const fieldsValues = fields2.split(",").map((value) => ___default.trim(value));
|
|
1158
|
+
return ___default.uniq([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3, ...fieldsValues]);
|
|
1159
|
+
}
|
|
1160
|
+
if (isStringArray$3(fields2)) {
|
|
1161
|
+
const fieldsValues = fields2.flatMap((value) => convertFieldsQueryParams(value, depth + 1)).filter((v) => !isNil(v));
|
|
1162
|
+
return ___default.uniq([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3, ...fieldsValues]);
|
|
1163
|
+
}
|
|
1164
|
+
throw new Error("Invalid fields parameter. Expected a string or an array of strings");
|
|
1165
|
+
};
|
|
1166
|
+
const isValidSchemaAttribute = (key, schema) => {
|
|
1167
|
+
if ([DOC_ID_ATTRIBUTE$3, ID_ATTRIBUTE$3].includes(key)) {
|
|
1168
|
+
return true;
|
|
1169
|
+
}
|
|
1170
|
+
if (!schema) {
|
|
1171
|
+
return false;
|
|
1172
|
+
}
|
|
1173
|
+
return Object.keys(schema.attributes).includes(key);
|
|
1174
|
+
};
|
|
1175
|
+
const convertFiltersQueryParams = (filters2, schema) => {
|
|
1176
|
+
if (!isObject(filters2)) {
|
|
1177
|
+
throw new Error("The filters parameter must be an object or an array");
|
|
1178
|
+
}
|
|
1179
|
+
const filtersCopy = cloneDeep(filters2);
|
|
1180
|
+
return convertAndSanitizeFilters(filtersCopy, schema);
|
|
1181
|
+
};
|
|
1182
|
+
const convertAndSanitizeFilters = (filters2, schema) => {
|
|
1183
|
+
if (Array.isArray(filters2)) {
|
|
1184
|
+
return filters2.map((filter) => convertAndSanitizeFilters(filter, schema)).filter((filter) => !isPlainObject(filter) || !isEmpty(filter));
|
|
1185
|
+
}
|
|
1186
|
+
if (!isPlainObject(filters2)) {
|
|
1187
|
+
return filters2;
|
|
1188
|
+
}
|
|
1189
|
+
const removeOperator = (operator) => delete filters2[operator];
|
|
1190
|
+
for (const [key, value] of Object.entries(filters2)) {
|
|
1191
|
+
const attribute = get(key, schema?.attributes);
|
|
1192
|
+
const validKey = isOperator(key) || isValidSchemaAttribute(key, schema);
|
|
1193
|
+
if (!validKey) {
|
|
1194
|
+
removeOperator(key);
|
|
1195
|
+
} else if (attribute) {
|
|
1196
|
+
if (attribute.type === "relation") {
|
|
1197
|
+
filters2[key] = convertAndSanitizeFilters(value, getModel(attribute.target));
|
|
1198
|
+
} else if (attribute.type === "component") {
|
|
1199
|
+
filters2[key] = convertAndSanitizeFilters(value, getModel(attribute.component));
|
|
1200
|
+
} else if (attribute.type === "media") {
|
|
1201
|
+
filters2[key] = convertAndSanitizeFilters(value, getModel("plugin::upload.file"));
|
|
1202
|
+
} else if (attribute.type === "dynamiczone") {
|
|
1203
|
+
removeOperator(key);
|
|
1204
|
+
} else if (attribute.type === "password") {
|
|
1205
|
+
removeOperator(key);
|
|
1206
|
+
} else {
|
|
1207
|
+
filters2[key] = convertAndSanitizeFilters(value, schema);
|
|
1208
|
+
}
|
|
1209
|
+
} else if (["$null", "$notNull"].includes(key)) {
|
|
1210
|
+
filters2[key] = parseType({ type: "boolean", value: filters2[key], forceCast: true });
|
|
1211
|
+
} else if (isObject(value)) {
|
|
1212
|
+
filters2[key] = convertAndSanitizeFilters(value, schema);
|
|
1213
|
+
}
|
|
1214
|
+
if (isPlainObject(filters2[key]) && isEmpty(filters2[key])) {
|
|
1215
|
+
removeOperator(key);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return filters2;
|
|
1219
|
+
};
|
|
1220
|
+
const convertStatusParams = (status, query = {}) => {
|
|
1221
|
+
query.filters = ({ meta }) => {
|
|
1222
|
+
const contentType = getModel(meta.uid);
|
|
1223
|
+
if (!contentType || !hasDraftAndPublish(contentType)) {
|
|
1224
|
+
return {};
|
|
1225
|
+
}
|
|
1226
|
+
return { [PUBLISHED_AT_ATTRIBUTE]: { $null: status === "draft" } };
|
|
1227
|
+
};
|
|
1228
|
+
};
|
|
1229
|
+
const transformQueryParams = (uid, params) => {
|
|
1230
|
+
const schema = getModel(uid);
|
|
1231
|
+
const query = {};
|
|
1232
|
+
const { _q, sort: sort2, filters: filters2, fields: fields2, populate: populate2, page, pageSize, start, limit, status, ...rest } = params;
|
|
1233
|
+
if (!isNil(status)) {
|
|
1234
|
+
convertStatusParams(status, query);
|
|
1235
|
+
}
|
|
1236
|
+
if (!isNil(_q)) {
|
|
1237
|
+
query._q = _q;
|
|
1238
|
+
}
|
|
1239
|
+
if (!isNil(sort2)) {
|
|
1240
|
+
query.orderBy = convertSortQueryParams(sort2);
|
|
1241
|
+
}
|
|
1242
|
+
if (!isNil(filters2)) {
|
|
1243
|
+
query.where = convertFiltersQueryParams(filters2, schema);
|
|
1244
|
+
}
|
|
1245
|
+
if (!isNil(fields2)) {
|
|
1246
|
+
query.select = convertFieldsQueryParams(fields2);
|
|
1247
|
+
}
|
|
1248
|
+
if (!isNil(populate2)) {
|
|
1249
|
+
query.populate = convertPopulateQueryParams(populate2, schema);
|
|
1250
|
+
}
|
|
1251
|
+
validatePaginationParams(page, pageSize, start, limit);
|
|
1252
|
+
if (!isNil(page)) {
|
|
1253
|
+
query.page = convertPageQueryParams(page);
|
|
1254
|
+
}
|
|
1255
|
+
if (!isNil(pageSize)) {
|
|
1256
|
+
query.pageSize = convertPageSizeQueryParams(pageSize, page);
|
|
1257
|
+
}
|
|
1258
|
+
if (!isNil(start)) {
|
|
1259
|
+
query.offset = convertStartQueryParams(start);
|
|
1260
|
+
}
|
|
1261
|
+
if (!isNil(limit)) {
|
|
1262
|
+
query.limit = convertLimitQueryParams(limit);
|
|
1263
|
+
}
|
|
1264
|
+
return {
|
|
1265
|
+
...rest,
|
|
1266
|
+
...query
|
|
1267
|
+
};
|
|
1268
|
+
};
|
|
1269
|
+
return {
|
|
1270
|
+
private_convertSortQueryParams: convertSortQueryParams,
|
|
1271
|
+
private_convertStartQueryParams: convertStartQueryParams,
|
|
1272
|
+
private_convertLimitQueryParams: convertLimitQueryParams,
|
|
1273
|
+
private_convertPopulateQueryParams: convertPopulateQueryParams,
|
|
1274
|
+
private_convertFiltersQueryParams: convertFiltersQueryParams,
|
|
1275
|
+
private_convertFieldsQueryParams: convertFieldsQueryParams,
|
|
1276
|
+
transformQueryParams
|
|
1277
|
+
};
|
|
1278
|
+
};
|
|
1279
|
+
const convertQueryParams = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1280
|
+
__proto__: null,
|
|
1281
|
+
createTransformer
|
|
1282
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1283
|
+
function pipe(...fns) {
|
|
1284
|
+
const [firstFn, ...fnRest] = fns;
|
|
1285
|
+
return async (...args) => {
|
|
1286
|
+
let res = await firstFn.apply(firstFn, args);
|
|
1287
|
+
for (let i = 0; i < fnRest.length; i += 1) {
|
|
1288
|
+
res = await fnRest[i](res);
|
|
1289
|
+
}
|
|
1290
|
+
return res;
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
const map = curry(pMap);
|
|
1294
|
+
const reduce = (mixedArray) => async (iteratee, initialValue) => {
|
|
1295
|
+
let acc = initialValue;
|
|
1296
|
+
for (let i = 0; i < mixedArray.length; i += 1) {
|
|
1297
|
+
acc = await iteratee(acc, await mixedArray[i], i);
|
|
1298
|
+
}
|
|
1299
|
+
return acc;
|
|
1300
|
+
};
|
|
1301
|
+
const async = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1302
|
+
__proto__: null,
|
|
1303
|
+
map,
|
|
1304
|
+
pipe,
|
|
1305
|
+
reduce
|
|
1306
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1307
|
+
const visitor$8 = ({ key, attribute }, { remove: remove2 }) => {
|
|
1308
|
+
if (attribute?.type === "password") {
|
|
1309
|
+
remove2(key);
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
const visitor$7 = ({ schema, key, attribute }, { remove: remove2 }) => {
|
|
1313
|
+
if (!attribute) {
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
|
|
1317
|
+
if (isPrivate) {
|
|
1318
|
+
remove2(key);
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
const ACTIONS_TO_VERIFY$1 = ["find"];
|
|
1322
|
+
const { CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$1 } = constants$1;
|
|
1323
|
+
const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schema }, { remove: remove2, set }) => {
|
|
1324
|
+
if (!attribute) {
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
const isRelation = attribute.type === "relation";
|
|
1328
|
+
if (!isRelation) {
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
const handleMorphRelation = async () => {
|
|
1332
|
+
const newMorphValue = [];
|
|
1333
|
+
for (const element of data[key]) {
|
|
1334
|
+
const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${element.__type}.${action}`);
|
|
1335
|
+
const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
|
|
1336
|
+
if (isAllowed) {
|
|
1337
|
+
newMorphValue.push(element);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
if (newMorphValue.length === 0) {
|
|
1341
|
+
remove2(key);
|
|
1342
|
+
} else {
|
|
1343
|
+
set(key, newMorphValue);
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
const handleRegularRelation = async () => {
|
|
1347
|
+
const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${attribute.target}.${action}`);
|
|
1348
|
+
const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
|
|
1349
|
+
if (!isAllowed) {
|
|
1350
|
+
remove2(key);
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
const isCreatorRelation = [CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE$1].includes(key);
|
|
1354
|
+
if (isMorphToRelationalAttribute(attribute)) {
|
|
1355
|
+
await handleMorphRelation();
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
if (isCreatorRelation && schema.options?.populateCreatorFields) {
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
await handleRegularRelation();
|
|
1362
|
+
};
|
|
1363
|
+
const hasAccessToSomeScopes$1 = async (scopes, auth) => {
|
|
1364
|
+
for (const scope of scopes) {
|
|
1365
|
+
try {
|
|
1366
|
+
await strapi.auth.verify(auth, { scope });
|
|
1367
|
+
return true;
|
|
1368
|
+
} catch {
|
|
1369
|
+
continue;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
return false;
|
|
1373
|
+
};
|
|
1374
|
+
const visitor$6 = ({ key, attribute }, { remove: remove2 }) => {
|
|
1375
|
+
if (isMorphToRelationalAttribute(attribute)) {
|
|
1376
|
+
remove2(key);
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
const visitor$5 = ({ key, attribute }, { remove: remove2 }) => {
|
|
1380
|
+
if (isDynamicZoneAttribute(attribute)) {
|
|
1381
|
+
remove2(key);
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
const removeDisallowedFields = (allowedFields = null) => ({ key, path: { attribute: path } }, { remove: remove2 }) => {
|
|
1385
|
+
if (allowedFields === null) {
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
if (!(isArray(allowedFields) && allowedFields.every(isString))) {
|
|
1389
|
+
throw new TypeError(
|
|
1390
|
+
`Expected array of strings for allowedFields but got "${typeof allowedFields}"`
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
if (isNil(path)) {
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
const containedPaths = getContainedPaths$1(path);
|
|
1397
|
+
const isPathAllowed = allowedFields.some(
|
|
1398
|
+
(p) => containedPaths.includes(p) || p.startsWith(`${path}.`)
|
|
1399
|
+
);
|
|
1400
|
+
if (isPathAllowed) {
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
remove2(key);
|
|
1404
|
+
};
|
|
1405
|
+
const getContainedPaths$1 = (path) => {
|
|
1406
|
+
const parts = toPath(path);
|
|
1407
|
+
return parts.reduce((acc, value, index2, list) => {
|
|
1408
|
+
return [...acc, list.slice(0, index2 + 1).join(".")];
|
|
1409
|
+
}, []);
|
|
1410
|
+
};
|
|
1411
|
+
const removeRestrictedFields = (restrictedFields = null) => ({ key, path: { attribute: path } }, { remove: remove2 }) => {
|
|
1412
|
+
if (restrictedFields === null) {
|
|
1413
|
+
remove2(key);
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {
|
|
1417
|
+
throw new TypeError(
|
|
1418
|
+
`Expected array of strings for restrictedFields but got "${typeof restrictedFields}"`
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
if (restrictedFields.includes(path)) {
|
|
1422
|
+
remove2(key);
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
const isRestrictedNested = restrictedFields.some(
|
|
1426
|
+
(allowedPath) => path?.toString().startsWith(`${allowedPath}.`)
|
|
1427
|
+
);
|
|
1428
|
+
if (isRestrictedNested) {
|
|
1429
|
+
remove2(key);
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
const visitor$4 = ({ schema, key, value }, { set }) => {
|
|
1433
|
+
if (key === "" && value === "*") {
|
|
1434
|
+
const { attributes } = schema;
|
|
1435
|
+
const newPopulateQuery = Object.entries(attributes).filter(
|
|
1436
|
+
([, attribute]) => ["relation", "component", "media", "dynamiczone"].includes(attribute.type)
|
|
1437
|
+
).reduce((acc, [key2]) => ({ ...acc, [key2]: true }), {});
|
|
1438
|
+
set("", newPopulateQuery);
|
|
1439
|
+
}
|
|
1440
|
+
};
|
|
1441
|
+
const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1442
|
+
__proto__: null,
|
|
1443
|
+
expandWildcardPopulate: visitor$4,
|
|
1444
|
+
removeDisallowedFields,
|
|
1445
|
+
removeDynamicZones: visitor$5,
|
|
1446
|
+
removeMorphToRelations: visitor$6,
|
|
1447
|
+
removePassword: visitor$8,
|
|
1448
|
+
removePrivate: visitor$7,
|
|
1449
|
+
removeRestrictedFields,
|
|
1450
|
+
removeRestrictedRelations
|
|
1451
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1452
|
+
const DEFAULT_PATH = { raw: null, attribute: null };
|
|
1453
|
+
const traverseFactory = () => {
|
|
1454
|
+
const state = {
|
|
1455
|
+
parsers: [],
|
|
1456
|
+
interceptors: [],
|
|
1457
|
+
ignore: [],
|
|
1458
|
+
handlers: {
|
|
1459
|
+
attributes: [],
|
|
1460
|
+
common: []
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
const traverse = async (visitor2, options, data) => {
|
|
1464
|
+
const { path = DEFAULT_PATH, schema, getModel } = options ?? {};
|
|
1465
|
+
for (const { predicate, handler } of state.interceptors) {
|
|
1466
|
+
if (predicate(data)) {
|
|
1467
|
+
return handler(visitor2, options, data, { recurse: traverse });
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
const parser = state.parsers.find((parser2) => parser2.predicate(data))?.parser;
|
|
1471
|
+
const utils2 = parser?.(data);
|
|
1472
|
+
if (!utils2) {
|
|
1473
|
+
return data;
|
|
1474
|
+
}
|
|
1475
|
+
let out = utils2.transform(data);
|
|
1476
|
+
const keys = utils2.keys(out);
|
|
1477
|
+
for (const key of keys) {
|
|
1478
|
+
const attribute = schema?.attributes?.[key];
|
|
1479
|
+
const newPath = { ...path };
|
|
1480
|
+
newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;
|
|
1481
|
+
if (!isNil(attribute)) {
|
|
1482
|
+
newPath.attribute = isNil(path.attribute) ? key : `${path.attribute}.${key}`;
|
|
1483
|
+
}
|
|
1484
|
+
const visitorOptions = {
|
|
1485
|
+
key,
|
|
1486
|
+
value: utils2.get(key, out),
|
|
1487
|
+
attribute,
|
|
1488
|
+
schema,
|
|
1489
|
+
path: newPath,
|
|
1490
|
+
data: out,
|
|
1491
|
+
getModel
|
|
1492
|
+
};
|
|
1493
|
+
const transformUtils = {
|
|
1494
|
+
remove(key2) {
|
|
1495
|
+
out = utils2.remove(key2, out);
|
|
1496
|
+
},
|
|
1497
|
+
set(key2, value2) {
|
|
1498
|
+
out = utils2.set(key2, value2, out);
|
|
1499
|
+
},
|
|
1500
|
+
recurse: traverse
|
|
1501
|
+
};
|
|
1502
|
+
await visitor2(visitorOptions, pick(["remove", "set"], transformUtils));
|
|
1503
|
+
const value = utils2.get(key, out);
|
|
1504
|
+
const createContext = () => ({
|
|
1505
|
+
key,
|
|
1506
|
+
value,
|
|
1507
|
+
attribute,
|
|
1508
|
+
schema,
|
|
1509
|
+
path: newPath,
|
|
1510
|
+
data: out,
|
|
1511
|
+
visitor: visitor2,
|
|
1512
|
+
getModel
|
|
1513
|
+
});
|
|
1514
|
+
const ignoreCtx = createContext();
|
|
1515
|
+
const shouldIgnore = state.ignore.some((predicate) => predicate(ignoreCtx));
|
|
1516
|
+
if (shouldIgnore) {
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
const handlers = [...state.handlers.common, ...state.handlers.attributes];
|
|
871
1520
|
for await (const handler of handlers) {
|
|
872
1521
|
const ctx = createContext();
|
|
873
1522
|
const pass = await handler.predicate(ctx);
|
|
@@ -949,33 +1598,33 @@ const filters = traverseFactory().intercept(
|
|
|
949
1598
|
}
|
|
950
1599
|
})).ignore(({ value }) => isNil(value)).on(
|
|
951
1600
|
({ attribute }) => isNil(attribute),
|
|
952
|
-
async ({ key, visitor: visitor2, path, value, schema }, { set, recurse }) => {
|
|
953
|
-
set(key, await recurse(visitor2, { schema, path }, value));
|
|
1601
|
+
async ({ key, visitor: visitor2, path, value, schema, getModel }, { set, recurse }) => {
|
|
1602
|
+
set(key, await recurse(visitor2, { schema, path, getModel }, value));
|
|
954
1603
|
}
|
|
955
|
-
).onRelation(async ({ key, attribute, visitor: visitor2, path, value }, { set, recurse }) => {
|
|
1604
|
+
).onRelation(async ({ key, attribute, visitor: visitor2, path, value, getModel }, { set, recurse }) => {
|
|
956
1605
|
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
|
957
1606
|
if (isMorphRelation) {
|
|
958
1607
|
return;
|
|
959
1608
|
}
|
|
960
1609
|
const targetSchemaUID = attribute.target;
|
|
961
|
-
const targetSchema =
|
|
962
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1610
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1611
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
963
1612
|
set(key, newValue);
|
|
964
|
-
}).onComponent(async ({ key, attribute, visitor: visitor2, path, value }, { set, recurse }) => {
|
|
965
|
-
const targetSchema =
|
|
966
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1613
|
+
}).onComponent(async ({ key, attribute, visitor: visitor2, path, value, getModel }, { set, recurse }) => {
|
|
1614
|
+
const targetSchema = getModel(attribute.component);
|
|
1615
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
967
1616
|
set(key, newValue);
|
|
968
|
-
}).onMedia(async ({ key, visitor: visitor2, path, value }, { set, recurse }) => {
|
|
1617
|
+
}).onMedia(async ({ key, visitor: visitor2, path, value, getModel }, { set, recurse }) => {
|
|
969
1618
|
const targetSchemaUID = "plugin::upload.file";
|
|
970
|
-
const targetSchema =
|
|
971
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1619
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1620
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
972
1621
|
set(key, newValue);
|
|
973
1622
|
});
|
|
974
1623
|
const traverseQueryFilters = curry(filters.traverse);
|
|
975
1624
|
const ORDERS = { asc: "asc", desc: "desc" };
|
|
976
1625
|
const ORDER_VALUES = Object.values(ORDERS);
|
|
977
1626
|
const isSortOrder = (value) => ORDER_VALUES.includes(value.toLowerCase());
|
|
978
|
-
const isStringArray$
|
|
1627
|
+
const isStringArray$2 = (value) => Array.isArray(value) && value.every(isString);
|
|
979
1628
|
const isObjectArray = (value) => Array.isArray(value) && value.every(isObject);
|
|
980
1629
|
const isNestedSorts = (value) => isString(value) && value.split(",").length > 1;
|
|
981
1630
|
const isObj$1 = (value) => isObject(value);
|
|
@@ -989,7 +1638,7 @@ const sort = traverseFactory().intercept(
|
|
|
989
1638
|
}
|
|
990
1639
|
).intercept(
|
|
991
1640
|
// Array of strings ['foo', 'foo,bar'] => map(recurse), then filter out empty items
|
|
992
|
-
isStringArray$
|
|
1641
|
+
isStringArray$2,
|
|
993
1642
|
async (visitor2, options, sort2, { recurse }) => {
|
|
994
1643
|
return Promise.all(sort2.map((nestedSort) => recurse(visitor2, options, nestedSort))).then(
|
|
995
1644
|
(res) => res.filter((nestedSort) => !isEmpty(nestedSort))
|
|
@@ -1056,23 +1705,23 @@ const sort = traverseFactory().intercept(
|
|
|
1056
1705
|
get(key, data) {
|
|
1057
1706
|
return data[key];
|
|
1058
1707
|
}
|
|
1059
|
-
})).onRelation(async ({ key, value, attribute, visitor: visitor2, path }, { set, recurse }) => {
|
|
1708
|
+
})).onRelation(async ({ key, value, attribute, visitor: visitor2, path, getModel }, { set, recurse }) => {
|
|
1060
1709
|
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
|
1061
1710
|
if (isMorphRelation) {
|
|
1062
1711
|
return;
|
|
1063
1712
|
}
|
|
1064
1713
|
const targetSchemaUID = attribute.target;
|
|
1065
|
-
const targetSchema =
|
|
1066
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1714
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1715
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
1067
1716
|
set(key, newValue);
|
|
1068
|
-
}).onMedia(async ({ key, path, visitor: visitor2, value }, { recurse, set }) => {
|
|
1717
|
+
}).onMedia(async ({ key, path, visitor: visitor2, value, getModel }, { recurse, set }) => {
|
|
1069
1718
|
const targetSchemaUID = "plugin::upload.file";
|
|
1070
|
-
const targetSchema =
|
|
1071
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1719
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1720
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
1072
1721
|
set(key, newValue);
|
|
1073
|
-
}).onComponent(async ({ key, value, visitor: visitor2, path, attribute }, { recurse, set }) => {
|
|
1074
|
-
const targetSchema =
|
|
1075
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1722
|
+
}).onComponent(async ({ key, value, visitor: visitor2, path, attribute, getModel }, { recurse, set }) => {
|
|
1723
|
+
const targetSchema = getModel(attribute.component);
|
|
1724
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
1076
1725
|
set(key, newValue);
|
|
1077
1726
|
});
|
|
1078
1727
|
const traverseQuerySort = curry(sort.traverse);
|
|
@@ -1081,9 +1730,9 @@ const isKeyword = (keyword) => {
|
|
|
1081
1730
|
return !attribute && keyword === key;
|
|
1082
1731
|
};
|
|
1083
1732
|
};
|
|
1084
|
-
const isStringArray$
|
|
1733
|
+
const isStringArray$1 = (value) => isArray(value) && value.every(isString);
|
|
1085
1734
|
const isObj = (value) => isObject(value);
|
|
1086
|
-
const populate = traverseFactory().intercept(isStringArray$
|
|
1735
|
+
const populate = traverseFactory().intercept(isStringArray$1, async (visitor2, options, populate2, { recurse }) => {
|
|
1087
1736
|
const visitedPopulate = await Promise.all(
|
|
1088
1737
|
populate2.map((nestedPopulate) => recurse(visitor2, options, nestedPopulate))
|
|
1089
1738
|
);
|
|
@@ -1159,180 +1808,100 @@ const populate = traverseFactory().intercept(isStringArray$2, async (visitor2, o
|
|
|
1159
1808
|
return ["sort", "filters", "fields"].includes(key) && !attribute;
|
|
1160
1809
|
}).on(
|
|
1161
1810
|
// Handle recursion on populate."populate"
|
|
1162
|
-
isKeyword("populate"),
|
|
1163
|
-
async ({ key, visitor: visitor2, path, value, schema }, { set, recurse }) => {
|
|
1164
|
-
const newValue = await recurse(visitor2, { schema, path }, value);
|
|
1165
|
-
set(key, newValue);
|
|
1166
|
-
}
|
|
1167
|
-
).on(isKeyword("on"), async ({ key, visitor: visitor2, path, value }, { set, recurse }) => {
|
|
1168
|
-
const newOn = {};
|
|
1169
|
-
if (!isObj(value)) {
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
for (const [uid, subPopulate] of Object.entries(value)) {
|
|
1173
|
-
const model = strapi.getModel(uid);
|
|
1174
|
-
const newPath = { ...path, raw: `${path.raw}[${uid}]` };
|
|
1175
|
-
newOn[uid] = await recurse(visitor2, { schema: model, path: newPath }, subPopulate);
|
|
1176
|
-
}
|
|
1177
|
-
set(key, newOn);
|
|
1178
|
-
}).onRelation(async ({ key, value, attribute, visitor: visitor2, path, schema }, { set, recurse }) => {
|
|
1179
|
-
if (isNil(value)) {
|
|
1180
|
-
return;
|
|
1181
|
-
}
|
|
1182
|
-
if (isMorphToRelationalAttribute(attribute)) {
|
|
1183
|
-
if (!isObject(value) || !("on" in value && isObject(value?.on))) {
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
const newValue2 = await recurse(visitor2, { schema, path }, { on: value?.on });
|
|
1187
|
-
set(key, { on: newValue2 });
|
|
1188
|
-
}
|
|
1189
|
-
const targetSchemaUID = attribute.target;
|
|
1190
|
-
const targetSchema = strapi.getModel(targetSchemaUID);
|
|
1191
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1192
|
-
set(key, newValue);
|
|
1193
|
-
}).onMedia(async ({ key, path, visitor: visitor2, value }, { recurse, set }) => {
|
|
1194
|
-
if (isNil(value)) {
|
|
1195
|
-
return;
|
|
1196
|
-
}
|
|
1197
|
-
const targetSchemaUID = "plugin::upload.file";
|
|
1198
|
-
const targetSchema = strapi.getModel(targetSchemaUID);
|
|
1199
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1200
|
-
set(key, newValue);
|
|
1201
|
-
}).onComponent(async ({ key, value, visitor: visitor2, path, attribute }, { recurse, set }) => {
|
|
1202
|
-
if (isNil(value)) {
|
|
1203
|
-
return;
|
|
1204
|
-
}
|
|
1205
|
-
const targetSchema = strapi.getModel(attribute.component);
|
|
1206
|
-
const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
|
|
1207
|
-
set(key, newValue);
|
|
1208
|
-
}).onDynamicZone(async ({ key, value, attribute, schema, visitor: visitor2, path }, { set, recurse }) => {
|
|
1209
|
-
if (isNil(value)) {
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
if (isObject(value)) {
|
|
1213
|
-
const { components } = attribute;
|
|
1214
|
-
const newValue = {};
|
|
1215
|
-
let newProperties = omit("on", value);
|
|
1216
|
-
for (const componentUID of components) {
|
|
1217
|
-
const componentSchema = strapi.getModel(componentUID);
|
|
1218
|
-
const properties = await recurse(visitor2, { schema: componentSchema, path }, value);
|
|
1219
|
-
newProperties = merge(newProperties, properties);
|
|
1220
|
-
}
|
|
1221
|
-
Object.assign(newValue, newProperties);
|
|
1222
|
-
if ("on" in value && value.on) {
|
|
1223
|
-
const newOn = await recurse(visitor2, { schema, path }, { on: value.on });
|
|
1224
|
-
Object.assign(newValue, newOn);
|
|
1225
|
-
}
|
|
1226
|
-
set(key, newValue);
|
|
1227
|
-
} else {
|
|
1228
|
-
const newValue = await recurse(visitor2, { schema, path }, value);
|
|
1229
|
-
set(key, newValue);
|
|
1230
|
-
}
|
|
1231
|
-
});
|
|
1232
|
-
const traverseQueryPopulate = curry(populate.traverse);
|
|
1233
|
-
const isStringArray$1 = (value) => isArray(value) && value.every(isString);
|
|
1234
|
-
const fields = traverseFactory().intercept(isStringArray$1, async (visitor2, options, fields2, { recurse }) => {
|
|
1235
|
-
return Promise.all(fields2.map((field) => recurse(visitor2, options, field)));
|
|
1236
|
-
}).intercept((value) => eq("*", value), constant("*")).parse(isString, () => ({
|
|
1237
|
-
transform: trim,
|
|
1238
|
-
remove(key, data) {
|
|
1239
|
-
return data === key ? void 0 : data;
|
|
1240
|
-
},
|
|
1241
|
-
set(_key, _value, data) {
|
|
1242
|
-
return data;
|
|
1243
|
-
},
|
|
1244
|
-
keys(data) {
|
|
1245
|
-
return [data];
|
|
1246
|
-
},
|
|
1247
|
-
get(key, data) {
|
|
1248
|
-
return key === data ? data : void 0;
|
|
1249
|
-
}
|
|
1250
|
-
}));
|
|
1251
|
-
const traverseQueryFields = curry(fields.traverse);
|
|
1252
|
-
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1253
|
-
__proto__: null,
|
|
1254
|
-
factory: traverseFactory,
|
|
1255
|
-
traverseQueryFields,
|
|
1256
|
-
traverseQueryFilters,
|
|
1257
|
-
traverseQueryPopulate,
|
|
1258
|
-
traverseQuerySort
|
|
1259
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
1260
|
-
const GROUP_OPERATORS = ["$and", "$or"];
|
|
1261
|
-
const WHERE_OPERATORS = [
|
|
1262
|
-
"$not",
|
|
1263
|
-
"$in",
|
|
1264
|
-
"$notIn",
|
|
1265
|
-
"$eq",
|
|
1266
|
-
"$eqi",
|
|
1267
|
-
"$ne",
|
|
1268
|
-
"$nei",
|
|
1269
|
-
"$gt",
|
|
1270
|
-
"$gte",
|
|
1271
|
-
"$lt",
|
|
1272
|
-
"$lte",
|
|
1273
|
-
"$null",
|
|
1274
|
-
"$notNull",
|
|
1275
|
-
"$between",
|
|
1276
|
-
"$startsWith",
|
|
1277
|
-
"$endsWith",
|
|
1278
|
-
"$startsWithi",
|
|
1279
|
-
"$endsWithi",
|
|
1280
|
-
"$contains",
|
|
1281
|
-
"$notContains",
|
|
1282
|
-
"$containsi",
|
|
1283
|
-
"$notContainsi",
|
|
1284
|
-
// Experimental, only for internal use
|
|
1285
|
-
"$jsonSupersetOf"
|
|
1286
|
-
];
|
|
1287
|
-
const CAST_OPERATORS = [
|
|
1288
|
-
"$not",
|
|
1289
|
-
"$in",
|
|
1290
|
-
"$notIn",
|
|
1291
|
-
"$eq",
|
|
1292
|
-
"$ne",
|
|
1293
|
-
"$gt",
|
|
1294
|
-
"$gte",
|
|
1295
|
-
"$lt",
|
|
1296
|
-
"$lte",
|
|
1297
|
-
"$between"
|
|
1298
|
-
];
|
|
1299
|
-
const ARRAY_OPERATORS = ["$in", "$notIn", "$between"];
|
|
1300
|
-
const OPERATORS = {
|
|
1301
|
-
where: WHERE_OPERATORS,
|
|
1302
|
-
cast: CAST_OPERATORS,
|
|
1303
|
-
group: GROUP_OPERATORS,
|
|
1304
|
-
array: ARRAY_OPERATORS
|
|
1305
|
-
};
|
|
1306
|
-
const OPERATORS_LOWERCASE = Object.fromEntries(
|
|
1307
|
-
Object.entries(OPERATORS).map(([key, values]) => [
|
|
1308
|
-
key,
|
|
1309
|
-
values.map((value) => value.toLowerCase())
|
|
1310
|
-
])
|
|
1311
|
-
);
|
|
1312
|
-
const isObjKey = (key, obj) => {
|
|
1313
|
-
return key in obj;
|
|
1314
|
-
};
|
|
1315
|
-
const isOperatorOfType = (type, key, ignoreCase = false) => {
|
|
1316
|
-
if (ignoreCase) {
|
|
1317
|
-
return OPERATORS_LOWERCASE[type]?.includes(key.toLowerCase()) ?? false;
|
|
1811
|
+
isKeyword("populate"),
|
|
1812
|
+
async ({ key, visitor: visitor2, path, value, schema, getModel }, { set, recurse }) => {
|
|
1813
|
+
const newValue = await recurse(visitor2, { schema, path, getModel }, value);
|
|
1814
|
+
set(key, newValue);
|
|
1318
1815
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1816
|
+
).on(isKeyword("on"), async ({ key, visitor: visitor2, path, value, getModel }, { set, recurse }) => {
|
|
1817
|
+
const newOn = {};
|
|
1818
|
+
if (!isObj(value)) {
|
|
1819
|
+
return;
|
|
1321
1820
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
const
|
|
1325
|
-
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1821
|
+
for (const [uid, subPopulate] of Object.entries(value)) {
|
|
1822
|
+
const model = getModel(uid);
|
|
1823
|
+
const newPath = { ...path, raw: `${path.raw}[${uid}]` };
|
|
1824
|
+
newOn[uid] = await recurse(visitor2, { schema: model, path: newPath, getModel }, subPopulate);
|
|
1825
|
+
}
|
|
1826
|
+
set(key, newOn);
|
|
1827
|
+
}).onRelation(
|
|
1828
|
+
async ({ key, value, attribute, visitor: visitor2, path, schema, getModel }, { set, recurse }) => {
|
|
1829
|
+
if (isNil(value)) {
|
|
1830
|
+
return;
|
|
1831
|
+
}
|
|
1832
|
+
if (isMorphToRelationalAttribute(attribute)) {
|
|
1833
|
+
if (!isObject(value) || !("on" in value && isObject(value?.on))) {
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
const newValue2 = await recurse(visitor2, { schema, path, getModel }, { on: value?.on });
|
|
1837
|
+
set(key, newValue2);
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
const targetSchemaUID = attribute.target;
|
|
1841
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1842
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
1843
|
+
set(key, newValue);
|
|
1844
|
+
}
|
|
1845
|
+
).onMedia(async ({ key, path, visitor: visitor2, value, getModel }, { recurse, set }) => {
|
|
1846
|
+
if (isNil(value)) {
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
const targetSchemaUID = "plugin::upload.file";
|
|
1850
|
+
const targetSchema = getModel(targetSchemaUID);
|
|
1851
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
1852
|
+
set(key, newValue);
|
|
1853
|
+
}).onComponent(async ({ key, value, visitor: visitor2, path, attribute, getModel }, { recurse, set }) => {
|
|
1854
|
+
if (isNil(value)) {
|
|
1855
|
+
return;
|
|
1856
|
+
}
|
|
1857
|
+
const targetSchema = getModel(attribute.component);
|
|
1858
|
+
const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
|
|
1859
|
+
set(key, newValue);
|
|
1860
|
+
}).onDynamicZone(async ({ key, value, schema, visitor: visitor2, path, getModel }, { set, recurse }) => {
|
|
1861
|
+
if (isNil(value) || !isObject(value)) {
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
if ("on" in value && value.on) {
|
|
1865
|
+
const newOn = await recurse(visitor2, { schema, path, getModel }, { on: value.on });
|
|
1866
|
+
set(key, newOn);
|
|
1867
|
+
}
|
|
1868
|
+
});
|
|
1869
|
+
const traverseQueryPopulate = curry(populate.traverse);
|
|
1870
|
+
const isStringArray = (value) => isArray(value) && value.every(isString);
|
|
1871
|
+
const fields = traverseFactory().intercept(isStringArray, async (visitor2, options, fields2, { recurse }) => {
|
|
1872
|
+
return Promise.all(fields2.map((field) => recurse(visitor2, options, field)));
|
|
1873
|
+
}).intercept((value) => eq("*", value), constant("*")).parse(isString, () => ({
|
|
1874
|
+
transform: trim,
|
|
1875
|
+
remove(key, data) {
|
|
1876
|
+
return data === key ? void 0 : data;
|
|
1877
|
+
},
|
|
1878
|
+
set(_key, _value, data) {
|
|
1879
|
+
return data;
|
|
1880
|
+
},
|
|
1881
|
+
keys(data) {
|
|
1882
|
+
return [data];
|
|
1883
|
+
},
|
|
1884
|
+
get(key, data) {
|
|
1885
|
+
return key === data ? data : void 0;
|
|
1886
|
+
}
|
|
1887
|
+
}));
|
|
1888
|
+
const traverseQueryFields = curry(fields.traverse);
|
|
1889
|
+
const index$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1890
|
+
__proto__: null,
|
|
1891
|
+
traverseQueryFields,
|
|
1892
|
+
traverseQueryFilters,
|
|
1893
|
+
traverseQueryPopulate,
|
|
1894
|
+
traverseQuerySort
|
|
1895
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1896
|
+
const { ID_ATTRIBUTE: ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$2 } = constants$1;
|
|
1897
|
+
const sanitizePasswords = (ctx) => async (entity) => {
|
|
1898
|
+
if (!ctx.schema) {
|
|
1330
1899
|
throw new Error("Missing schema in sanitizePasswords");
|
|
1331
1900
|
}
|
|
1332
|
-
return traverseEntity$1(visitor$8,
|
|
1901
|
+
return traverseEntity$1(visitor$8, ctx, entity);
|
|
1333
1902
|
};
|
|
1334
|
-
const defaultSanitizeOutput = async (
|
|
1335
|
-
if (!schema) {
|
|
1903
|
+
const defaultSanitizeOutput = async (ctx, entity) => {
|
|
1904
|
+
if (!ctx.schema) {
|
|
1336
1905
|
throw new Error("Missing schema in defaultSanitizeOutput");
|
|
1337
1906
|
}
|
|
1338
1907
|
return traverseEntity$1(
|
|
@@ -1340,139 +1909,121 @@ const defaultSanitizeOutput = async (schema, entity) => {
|
|
|
1340
1909
|
visitor$8(...args);
|
|
1341
1910
|
visitor$7(...args);
|
|
1342
1911
|
},
|
|
1343
|
-
|
|
1912
|
+
ctx,
|
|
1344
1913
|
entity
|
|
1345
1914
|
);
|
|
1346
1915
|
};
|
|
1347
|
-
const defaultSanitizeFilters = curry((
|
|
1348
|
-
if (!schema) {
|
|
1916
|
+
const defaultSanitizeFilters = curry((ctx, filters2) => {
|
|
1917
|
+
if (!ctx.schema) {
|
|
1349
1918
|
throw new Error("Missing schema in defaultSanitizeFilters");
|
|
1350
1919
|
}
|
|
1351
1920
|
return pipe(
|
|
1352
1921
|
// Remove keys that are not attributes or valid operators
|
|
1353
|
-
traverseQueryFilters(
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
},
|
|
1363
|
-
{ schema }
|
|
1364
|
-
),
|
|
1922
|
+
traverseQueryFilters(({ key, attribute }, { remove: remove2 }) => {
|
|
1923
|
+
const isAttribute = !!attribute;
|
|
1924
|
+
if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
|
|
1925
|
+
return;
|
|
1926
|
+
}
|
|
1927
|
+
if (!isAttribute && !isOperator(key)) {
|
|
1928
|
+
remove2(key);
|
|
1929
|
+
}
|
|
1930
|
+
}, ctx),
|
|
1365
1931
|
// Remove dynamic zones from filters
|
|
1366
|
-
traverseQueryFilters(visitor$5,
|
|
1932
|
+
traverseQueryFilters(visitor$5, ctx),
|
|
1367
1933
|
// Remove morpTo relations from filters
|
|
1368
|
-
traverseQueryFilters(visitor$6,
|
|
1934
|
+
traverseQueryFilters(visitor$6, ctx),
|
|
1369
1935
|
// Remove passwords from filters
|
|
1370
|
-
traverseQueryFilters(visitor$8,
|
|
1936
|
+
traverseQueryFilters(visitor$8, ctx),
|
|
1371
1937
|
// Remove private from filters
|
|
1372
|
-
traverseQueryFilters(visitor$7,
|
|
1938
|
+
traverseQueryFilters(visitor$7, ctx),
|
|
1373
1939
|
// Remove empty objects
|
|
1374
|
-
traverseQueryFilters(
|
|
1375
|
-
(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
},
|
|
1380
|
-
{ schema }
|
|
1381
|
-
)
|
|
1940
|
+
traverseQueryFilters(({ key, value }, { remove: remove2 }) => {
|
|
1941
|
+
if (isObject(value) && isEmpty(value)) {
|
|
1942
|
+
remove2(key);
|
|
1943
|
+
}
|
|
1944
|
+
}, ctx)
|
|
1382
1945
|
)(filters2);
|
|
1383
1946
|
});
|
|
1384
|
-
const defaultSanitizeSort = curry((
|
|
1385
|
-
if (!schema) {
|
|
1947
|
+
const defaultSanitizeSort = curry((ctx, sort2) => {
|
|
1948
|
+
if (!ctx.schema) {
|
|
1386
1949
|
throw new Error("Missing schema in defaultSanitizeSort");
|
|
1387
1950
|
}
|
|
1388
1951
|
return pipe(
|
|
1389
1952
|
// Remove non attribute keys
|
|
1390
|
-
traverseQuerySort(
|
|
1391
|
-
(
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
},
|
|
1399
|
-
{ schema }
|
|
1400
|
-
),
|
|
1953
|
+
traverseQuerySort(({ key, attribute }, { remove: remove2 }) => {
|
|
1954
|
+
if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1957
|
+
if (!attribute) {
|
|
1958
|
+
remove2(key);
|
|
1959
|
+
}
|
|
1960
|
+
}, ctx),
|
|
1401
1961
|
// Remove dynamic zones from sort
|
|
1402
|
-
traverseQuerySort(visitor$5,
|
|
1962
|
+
traverseQuerySort(visitor$5, ctx),
|
|
1403
1963
|
// Remove morpTo relations from sort
|
|
1404
|
-
traverseQuerySort(visitor$6,
|
|
1964
|
+
traverseQuerySort(visitor$6, ctx),
|
|
1405
1965
|
// Remove private from sort
|
|
1406
|
-
traverseQuerySort(visitor$7,
|
|
1966
|
+
traverseQuerySort(visitor$7, ctx),
|
|
1407
1967
|
// Remove passwords from filters
|
|
1408
|
-
traverseQuerySort(visitor$8,
|
|
1968
|
+
traverseQuerySort(visitor$8, ctx),
|
|
1409
1969
|
// Remove keys for empty non-scalar values
|
|
1410
|
-
traverseQuerySort(
|
|
1411
|
-
(
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
},
|
|
1419
|
-
{ schema }
|
|
1420
|
-
)
|
|
1970
|
+
traverseQuerySort(({ key, attribute, value }, { remove: remove2 }) => {
|
|
1971
|
+
if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
if (!isScalarAttribute(attribute) && isEmpty(value)) {
|
|
1975
|
+
remove2(key);
|
|
1976
|
+
}
|
|
1977
|
+
}, ctx)
|
|
1421
1978
|
)(sort2);
|
|
1422
1979
|
});
|
|
1423
|
-
const defaultSanitizeFields = curry((
|
|
1424
|
-
if (!schema) {
|
|
1980
|
+
const defaultSanitizeFields = curry((ctx, fields2) => {
|
|
1981
|
+
if (!ctx.schema) {
|
|
1425
1982
|
throw new Error("Missing schema in defaultSanitizeFields");
|
|
1426
1983
|
}
|
|
1427
1984
|
return pipe(
|
|
1428
1985
|
// Only keep scalar attributes
|
|
1429
|
-
traverseQueryFields(
|
|
1430
|
-
(
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
},
|
|
1438
|
-
{ schema }
|
|
1439
|
-
),
|
|
1986
|
+
traverseQueryFields(({ key, attribute }, { remove: remove2 }) => {
|
|
1987
|
+
if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
|
|
1988
|
+
return;
|
|
1989
|
+
}
|
|
1990
|
+
if (isNil(attribute) || !isScalarAttribute(attribute)) {
|
|
1991
|
+
remove2(key);
|
|
1992
|
+
}
|
|
1993
|
+
}, ctx),
|
|
1440
1994
|
// Remove private fields
|
|
1441
|
-
traverseQueryFields(visitor$7,
|
|
1995
|
+
traverseQueryFields(visitor$7, ctx),
|
|
1442
1996
|
// Remove password fields
|
|
1443
|
-
traverseQueryFields(visitor$8,
|
|
1997
|
+
traverseQueryFields(visitor$8, ctx),
|
|
1444
1998
|
// Remove nil values from fields array
|
|
1445
1999
|
(value) => isArray(value) ? value.filter((field) => !isNil(field)) : value
|
|
1446
2000
|
)(fields2);
|
|
1447
2001
|
});
|
|
1448
|
-
const defaultSanitizePopulate = curry((
|
|
1449
|
-
if (!schema) {
|
|
2002
|
+
const defaultSanitizePopulate = curry((ctx, populate2) => {
|
|
2003
|
+
if (!ctx.schema) {
|
|
1450
2004
|
throw new Error("Missing schema in defaultSanitizePopulate");
|
|
1451
2005
|
}
|
|
1452
2006
|
return pipe(
|
|
1453
|
-
traverseQueryPopulate(visitor$4,
|
|
1454
|
-
traverseQueryPopulate(
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
},
|
|
1472
|
-
{ schema }
|
|
1473
|
-
),
|
|
2007
|
+
traverseQueryPopulate(visitor$4, ctx),
|
|
2008
|
+
traverseQueryPopulate(async ({ key, value, schema, attribute, getModel }, { set }) => {
|
|
2009
|
+
if (attribute) {
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
2012
|
+
if (key === "sort") {
|
|
2013
|
+
set(key, await defaultSanitizeSort({ schema, getModel }, value));
|
|
2014
|
+
}
|
|
2015
|
+
if (key === "filters") {
|
|
2016
|
+
set(key, await defaultSanitizeFilters({ schema, getModel }, value));
|
|
2017
|
+
}
|
|
2018
|
+
if (key === "fields") {
|
|
2019
|
+
set(key, await defaultSanitizeFields({ schema, getModel }, value));
|
|
2020
|
+
}
|
|
2021
|
+
if (key === "populate") {
|
|
2022
|
+
set(key, await defaultSanitizePopulate({ schema, getModel }, value));
|
|
2023
|
+
}
|
|
2024
|
+
}, ctx),
|
|
1474
2025
|
// Remove private fields
|
|
1475
|
-
traverseQueryPopulate(visitor$7,
|
|
2026
|
+
traverseQueryPopulate(visitor$7, ctx)
|
|
1476
2027
|
)(populate2);
|
|
1477
2028
|
});
|
|
1478
2029
|
const sanitizers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -1484,7 +2035,8 @@ const sanitizers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
1484
2035
|
defaultSanitizeSort,
|
|
1485
2036
|
sanitizePasswords
|
|
1486
2037
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1487
|
-
const
|
|
2038
|
+
const createAPISanitizers = (opts) => {
|
|
2039
|
+
const { getModel } = opts;
|
|
1488
2040
|
const sanitizeInput = (data, schema, { auth } = {}) => {
|
|
1489
2041
|
if (!schema) {
|
|
1490
2042
|
throw new Error("Missing schema in sanitizeInput");
|
|
@@ -1498,12 +2050,14 @@ const createContentAPISanitizers = () => {
|
|
|
1498
2050
|
omit(constants$1.ID_ATTRIBUTE),
|
|
1499
2051
|
omit(constants$1.DOC_ID_ATTRIBUTE),
|
|
1500
2052
|
// Remove non-writable attributes
|
|
1501
|
-
traverseEntity$1(removeRestrictedFields(nonWritableAttributes), { schema })
|
|
2053
|
+
traverseEntity$1(removeRestrictedFields(nonWritableAttributes), { schema, getModel })
|
|
1502
2054
|
];
|
|
1503
2055
|
if (auth) {
|
|
1504
|
-
transforms.push(
|
|
2056
|
+
transforms.push(
|
|
2057
|
+
traverseEntity$1(removeRestrictedRelations(auth), { schema, getModel })
|
|
2058
|
+
);
|
|
1505
2059
|
}
|
|
1506
|
-
|
|
2060
|
+
opts?.sanitizers?.input?.forEach((sanitizer) => transforms.push(sanitizer(schema)));
|
|
1507
2061
|
return pipe(...transforms)(data);
|
|
1508
2062
|
};
|
|
1509
2063
|
const sanitizeOutput = async (data, schema, { auth } = {}) => {
|
|
@@ -1517,11 +2071,15 @@ const createContentAPISanitizers = () => {
|
|
|
1517
2071
|
}
|
|
1518
2072
|
return res;
|
|
1519
2073
|
}
|
|
1520
|
-
const transforms = [
|
|
2074
|
+
const transforms = [
|
|
2075
|
+
(data2) => defaultSanitizeOutput({ schema, getModel }, data2)
|
|
2076
|
+
];
|
|
1521
2077
|
if (auth) {
|
|
1522
|
-
transforms.push(
|
|
2078
|
+
transforms.push(
|
|
2079
|
+
traverseEntity$1(removeRestrictedRelations(auth), { schema, getModel })
|
|
2080
|
+
);
|
|
1523
2081
|
}
|
|
1524
|
-
|
|
2082
|
+
opts?.sanitizers?.output?.forEach((sanitizer) => transforms.push(sanitizer(schema)));
|
|
1525
2083
|
return pipe(...transforms)(data);
|
|
1526
2084
|
};
|
|
1527
2085
|
const sanitizeQuery = async (query, schema, { auth } = {}) => {
|
|
@@ -1551,9 +2109,11 @@ const createContentAPISanitizers = () => {
|
|
|
1551
2109
|
if (isArray(filters2)) {
|
|
1552
2110
|
return Promise.all(filters2.map((filter) => sanitizeFilters(filter, schema, { auth })));
|
|
1553
2111
|
}
|
|
1554
|
-
const transforms = [defaultSanitizeFilters(schema)];
|
|
2112
|
+
const transforms = [defaultSanitizeFilters({ schema, getModel })];
|
|
1555
2113
|
if (auth) {
|
|
1556
|
-
transforms.push(
|
|
2114
|
+
transforms.push(
|
|
2115
|
+
traverseQueryFilters(removeRestrictedRelations(auth), { schema, getModel })
|
|
2116
|
+
);
|
|
1557
2117
|
}
|
|
1558
2118
|
return pipe(...transforms)(filters2);
|
|
1559
2119
|
};
|
|
@@ -1561,9 +2121,11 @@ const createContentAPISanitizers = () => {
|
|
|
1561
2121
|
if (!schema) {
|
|
1562
2122
|
throw new Error("Missing schema in sanitizeSort");
|
|
1563
2123
|
}
|
|
1564
|
-
const transforms = [defaultSanitizeSort(schema)];
|
|
2124
|
+
const transforms = [defaultSanitizeSort({ schema, getModel })];
|
|
1565
2125
|
if (auth) {
|
|
1566
|
-
transforms.push(
|
|
2126
|
+
transforms.push(
|
|
2127
|
+
traverseQuerySort(removeRestrictedRelations(auth), { schema, getModel })
|
|
2128
|
+
);
|
|
1567
2129
|
}
|
|
1568
2130
|
return pipe(...transforms)(sort2);
|
|
1569
2131
|
};
|
|
@@ -1571,16 +2133,18 @@ const createContentAPISanitizers = () => {
|
|
|
1571
2133
|
if (!schema) {
|
|
1572
2134
|
throw new Error("Missing schema in sanitizeFields");
|
|
1573
2135
|
}
|
|
1574
|
-
const transforms = [defaultSanitizeFields(schema)];
|
|
2136
|
+
const transforms = [defaultSanitizeFields({ schema, getModel })];
|
|
1575
2137
|
return pipe(...transforms)(fields2);
|
|
1576
2138
|
};
|
|
1577
2139
|
const sanitizePopulate = (populate2, schema, { auth } = {}) => {
|
|
1578
2140
|
if (!schema) {
|
|
1579
2141
|
throw new Error("Missing schema in sanitizePopulate");
|
|
1580
2142
|
}
|
|
1581
|
-
const transforms = [defaultSanitizePopulate(schema)];
|
|
2143
|
+
const transforms = [defaultSanitizePopulate({ schema, getModel })];
|
|
1582
2144
|
if (auth) {
|
|
1583
|
-
transforms.push(
|
|
2145
|
+
transforms.push(
|
|
2146
|
+
traverseQueryPopulate(removeRestrictedRelations(auth), { schema, getModel })
|
|
2147
|
+
);
|
|
1584
2148
|
}
|
|
1585
2149
|
return pipe(...transforms)(populate2);
|
|
1586
2150
|
};
|
|
@@ -1594,126 +2158,22 @@ const createContentAPISanitizers = () => {
|
|
|
1594
2158
|
populate: sanitizePopulate
|
|
1595
2159
|
};
|
|
1596
2160
|
};
|
|
1597
|
-
const
|
|
1598
|
-
const index$1 = {
|
|
1599
|
-
contentAPI: contentAPI$1,
|
|
1600
|
-
sanitizers,
|
|
1601
|
-
visitors: visitors$1
|
|
1602
|
-
};
|
|
1603
|
-
const formatYupInnerError = (yupError) => ({
|
|
1604
|
-
path: toPath(yupError.path),
|
|
1605
|
-
message: yupError.message,
|
|
1606
|
-
name: yupError.name
|
|
1607
|
-
});
|
|
1608
|
-
const formatYupErrors = (yupError) => ({
|
|
1609
|
-
errors: isEmpty(yupError.inner) ? [formatYupInnerError(yupError)] : yupError.inner.map(formatYupInnerError),
|
|
1610
|
-
message: yupError.message
|
|
1611
|
-
});
|
|
1612
|
-
class ApplicationError extends Error {
|
|
1613
|
-
name;
|
|
1614
|
-
details;
|
|
1615
|
-
message;
|
|
1616
|
-
constructor(message = "An application error occured", details = {}) {
|
|
1617
|
-
super();
|
|
1618
|
-
this.name = "ApplicationError";
|
|
1619
|
-
this.message = message;
|
|
1620
|
-
this.details = details;
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
class ValidationError extends ApplicationError {
|
|
1624
|
-
constructor(message, details) {
|
|
1625
|
-
super(message, details);
|
|
1626
|
-
this.name = "ValidationError";
|
|
1627
|
-
}
|
|
1628
|
-
}
|
|
1629
|
-
class YupValidationError extends ValidationError {
|
|
1630
|
-
constructor(yupError, message) {
|
|
1631
|
-
super("Validation");
|
|
1632
|
-
const { errors: errors2, message: yupMessage } = formatYupErrors(yupError);
|
|
1633
|
-
this.message = message || yupMessage;
|
|
1634
|
-
this.details = { errors: errors2 };
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
class PaginationError extends ApplicationError {
|
|
1638
|
-
constructor(message = "Invalid pagination", details) {
|
|
1639
|
-
super(message, details);
|
|
1640
|
-
this.name = "PaginationError";
|
|
1641
|
-
this.message = message;
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
class NotFoundError extends ApplicationError {
|
|
1645
|
-
constructor(message = "Entity not found", details) {
|
|
1646
|
-
super(message, details);
|
|
1647
|
-
this.name = "NotFoundError";
|
|
1648
|
-
this.message = message;
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
class ForbiddenError extends ApplicationError {
|
|
1652
|
-
constructor(message = "Forbidden access", details) {
|
|
1653
|
-
super(message, details);
|
|
1654
|
-
this.name = "ForbiddenError";
|
|
1655
|
-
this.message = message;
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
class UnauthorizedError extends ApplicationError {
|
|
1659
|
-
constructor(message = "Unauthorized", details) {
|
|
1660
|
-
super(message, details);
|
|
1661
|
-
this.name = "UnauthorizedError";
|
|
1662
|
-
this.message = message;
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
class RateLimitError extends ApplicationError {
|
|
1666
|
-
constructor(message = "Too many requests, please try again later.", details) {
|
|
1667
|
-
super(message, details);
|
|
1668
|
-
this.name = "RateLimitError";
|
|
1669
|
-
this.message = message;
|
|
1670
|
-
this.details = details || {};
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
class PayloadTooLargeError extends ApplicationError {
|
|
1674
|
-
constructor(message = "Entity too large", details) {
|
|
1675
|
-
super(message, details);
|
|
1676
|
-
this.name = "PayloadTooLargeError";
|
|
1677
|
-
this.message = message;
|
|
1678
|
-
}
|
|
1679
|
-
}
|
|
1680
|
-
class PolicyError extends ForbiddenError {
|
|
1681
|
-
constructor(message = "Policy Failed", details) {
|
|
1682
|
-
super(message, details);
|
|
1683
|
-
this.name = "PolicyError";
|
|
1684
|
-
this.message = message;
|
|
1685
|
-
this.details = details || {};
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
class NotImplementedError extends ApplicationError {
|
|
1689
|
-
constructor(message = "This feature is not implemented yet", details) {
|
|
1690
|
-
super(message, details);
|
|
1691
|
-
this.name = "NotImplementedError";
|
|
1692
|
-
this.message = message;
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
const errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2161
|
+
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1696
2162
|
__proto__: null,
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
NotFoundError,
|
|
1701
|
-
NotImplementedError,
|
|
1702
|
-
PaginationError,
|
|
1703
|
-
PayloadTooLargeError,
|
|
1704
|
-
PolicyError,
|
|
1705
|
-
RateLimitError,
|
|
1706
|
-
UnauthorizedError,
|
|
1707
|
-
ValidationError,
|
|
1708
|
-
YupValidationError
|
|
2163
|
+
createAPISanitizers,
|
|
2164
|
+
sanitizers,
|
|
2165
|
+
visitors: index$4
|
|
1709
2166
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1710
|
-
const
|
|
1711
|
-
const msg = path && path !== key ? `Invalid
|
|
1712
|
-
throw new ValidationError(msg
|
|
2167
|
+
const throwInvalidKey = ({ key, path }) => {
|
|
2168
|
+
const msg = path && path !== key ? `Invalid key ${key} at ${path}` : `Invalid key ${key}`;
|
|
2169
|
+
throw new ValidationError(msg, {
|
|
2170
|
+
key,
|
|
2171
|
+
path
|
|
2172
|
+
});
|
|
1713
2173
|
};
|
|
1714
2174
|
const visitor$3 = ({ key, attribute, path }) => {
|
|
1715
2175
|
if (attribute?.type === "password") {
|
|
1716
|
-
|
|
2176
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
1717
2177
|
}
|
|
1718
2178
|
};
|
|
1719
2179
|
const visitor$2 = ({ schema, key, attribute, path }) => {
|
|
@@ -1722,7 +2182,7 @@ const visitor$2 = ({ schema, key, attribute, path }) => {
|
|
|
1722
2182
|
}
|
|
1723
2183
|
const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
|
|
1724
2184
|
if (isPrivate) {
|
|
1725
|
-
|
|
2185
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
1726
2186
|
}
|
|
1727
2187
|
};
|
|
1728
2188
|
const ACTIONS_TO_VERIFY = ["find"];
|
|
@@ -1740,7 +2200,7 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
|
|
|
1740
2200
|
const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);
|
|
1741
2201
|
const isAllowed = await hasAccessToSomeScopes(scopes, auth);
|
|
1742
2202
|
if (!isAllowed) {
|
|
1743
|
-
|
|
2203
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
1744
2204
|
}
|
|
1745
2205
|
}
|
|
1746
2206
|
};
|
|
@@ -1748,7 +2208,7 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
|
|
|
1748
2208
|
const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);
|
|
1749
2209
|
const isAllowed = await hasAccessToSomeScopes(scopes, auth);
|
|
1750
2210
|
if (!isAllowed) {
|
|
1751
|
-
|
|
2211
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
1752
2212
|
}
|
|
1753
2213
|
};
|
|
1754
2214
|
const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);
|
|
@@ -1774,12 +2234,12 @@ const hasAccessToSomeScopes = async (scopes, auth) => {
|
|
|
1774
2234
|
};
|
|
1775
2235
|
const visitor$1 = ({ key, attribute, path }) => {
|
|
1776
2236
|
if (isMorphToRelationalAttribute(attribute)) {
|
|
1777
|
-
|
|
2237
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
1778
2238
|
}
|
|
1779
2239
|
};
|
|
1780
2240
|
const visitor = ({ key, attribute, path }) => {
|
|
1781
2241
|
if (isDynamicZoneAttribute(attribute)) {
|
|
1782
|
-
|
|
2242
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
1783
2243
|
}
|
|
1784
2244
|
};
|
|
1785
2245
|
const throwDisallowedFields = (allowedFields = null) => ({ key, path: { attribute: path } }) => {
|
|
@@ -1801,7 +2261,7 @@ const throwDisallowedFields = (allowedFields = null) => ({ key, path: { attribut
|
|
|
1801
2261
|
if (isPathAllowed) {
|
|
1802
2262
|
return;
|
|
1803
2263
|
}
|
|
1804
|
-
|
|
2264
|
+
throwInvalidKey({ key, path });
|
|
1805
2265
|
};
|
|
1806
2266
|
const getContainedPaths = (path) => {
|
|
1807
2267
|
const parts = toPath(path);
|
|
@@ -1811,7 +2271,7 @@ const getContainedPaths = (path) => {
|
|
|
1811
2271
|
};
|
|
1812
2272
|
const throwRestrictedFields = (restrictedFields = null) => ({ key, path: { attribute: path } }) => {
|
|
1813
2273
|
if (restrictedFields === null) {
|
|
1814
|
-
|
|
2274
|
+
throwInvalidKey({ key, path });
|
|
1815
2275
|
}
|
|
1816
2276
|
if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {
|
|
1817
2277
|
throw new TypeError(
|
|
@@ -1819,16 +2279,46 @@ const throwRestrictedFields = (restrictedFields = null) => ({ key, path: { attri
|
|
|
1819
2279
|
);
|
|
1820
2280
|
}
|
|
1821
2281
|
if (restrictedFields.includes(path)) {
|
|
1822
|
-
|
|
2282
|
+
throwInvalidKey({ key, path });
|
|
1823
2283
|
}
|
|
1824
2284
|
const isRestrictedNested = restrictedFields.some(
|
|
1825
2285
|
(allowedPath) => path?.toString().startsWith(`${allowedPath}.`)
|
|
1826
2286
|
);
|
|
1827
2287
|
if (isRestrictedNested) {
|
|
1828
|
-
|
|
2288
|
+
throwInvalidKey({ key, path });
|
|
2289
|
+
}
|
|
2290
|
+
};
|
|
2291
|
+
const ID_FIELDS = [constants$1.DOC_ID_ATTRIBUTE, constants$1.DOC_ID_ATTRIBUTE];
|
|
2292
|
+
const ALLOWED_ROOT_LEVEL_FIELDS = [...ID_FIELDS];
|
|
2293
|
+
const MORPH_TO_ALLOWED_FIELDS = ["__type"];
|
|
2294
|
+
const DYNAMIC_ZONE_ALLOWED_FIELDS = ["__component"];
|
|
2295
|
+
const RELATION_REORDERING_FIELDS = ["connect", "disconnect", "set", "options"];
|
|
2296
|
+
const throwUnrecognizedFields = ({ key, attribute, path, schema, parent }) => {
|
|
2297
|
+
if (attribute) {
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
if (path.attribute === null) {
|
|
2301
|
+
if (ALLOWED_ROOT_LEVEL_FIELDS.includes(key)) {
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
return throwInvalidKey({ key, path: attribute });
|
|
2305
|
+
}
|
|
2306
|
+
if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_ALLOWED_FIELDS.includes(key)) {
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2309
|
+
if (isComponentSchema(schema) && isDynamicZoneAttribute(parent?.attribute) && DYNAMIC_ZONE_ALLOWED_FIELDS.includes(key)) {
|
|
2310
|
+
return;
|
|
2311
|
+
}
|
|
2312
|
+
if (hasRelationReordering(parent?.attribute) && RELATION_REORDERING_FIELDS.includes(key)) {
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
const canUseID = isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute);
|
|
2316
|
+
if (canUseID && !ID_FIELDS.includes(key)) {
|
|
2317
|
+
return;
|
|
1829
2318
|
}
|
|
2319
|
+
throwInvalidKey({ key, path: attribute });
|
|
1830
2320
|
};
|
|
1831
|
-
const
|
|
2321
|
+
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1832
2322
|
__proto__: null,
|
|
1833
2323
|
throwDisallowedFields,
|
|
1834
2324
|
throwDynamicZones: visitor,
|
|
@@ -1836,133 +2326,155 @@ const visitors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
|
|
|
1836
2326
|
throwPassword: visitor$3,
|
|
1837
2327
|
throwPrivate: visitor$2,
|
|
1838
2328
|
throwRestrictedFields,
|
|
1839
|
-
throwRestrictedRelations
|
|
2329
|
+
throwRestrictedRelations,
|
|
2330
|
+
throwUnrecognizedFields
|
|
1840
2331
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1841
|
-
const { ID_ATTRIBUTE: ID_ATTRIBUTE$
|
|
1842
|
-
const throwPasswords = (
|
|
1843
|
-
if (!schema) {
|
|
2332
|
+
const { ID_ATTRIBUTE: ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$1 } = constants$1;
|
|
2333
|
+
const throwPasswords = (ctx) => async (entity) => {
|
|
2334
|
+
if (!ctx.schema) {
|
|
1844
2335
|
throw new Error("Missing schema in throwPasswords");
|
|
1845
2336
|
}
|
|
1846
|
-
return traverseEntity$1(visitor$3,
|
|
2337
|
+
return traverseEntity$1(visitor$3, ctx, entity);
|
|
1847
2338
|
};
|
|
1848
|
-
const defaultValidateFilters = curry((
|
|
1849
|
-
if (!schema) {
|
|
2339
|
+
const defaultValidateFilters = curry((ctx, filters2) => {
|
|
2340
|
+
if (!ctx.schema) {
|
|
1850
2341
|
throw new Error("Missing schema in defaultValidateFilters");
|
|
1851
2342
|
}
|
|
1852
2343
|
return pipe(
|
|
1853
2344
|
// keys that are not attributes or valid operators
|
|
1854
|
-
traverseQueryFilters(
|
|
1855
|
-
(
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
},
|
|
1864
|
-
{ schema }
|
|
1865
|
-
),
|
|
2345
|
+
traverseQueryFilters(({ key, attribute, path }) => {
|
|
2346
|
+
if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
const isAttribute = !!attribute;
|
|
2350
|
+
if (!isAttribute && !isOperator(key)) {
|
|
2351
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
2352
|
+
}
|
|
2353
|
+
}, ctx),
|
|
1866
2354
|
// dynamic zones from filters
|
|
1867
|
-
traverseQueryFilters(visitor,
|
|
2355
|
+
traverseQueryFilters(visitor, ctx),
|
|
1868
2356
|
// morphTo relations from filters; because you can't have deep filtering on morph relations
|
|
1869
|
-
traverseQueryFilters(visitor$1,
|
|
2357
|
+
traverseQueryFilters(visitor$1, ctx),
|
|
1870
2358
|
// passwords from filters
|
|
1871
|
-
traverseQueryFilters(visitor$3,
|
|
2359
|
+
traverseQueryFilters(visitor$3, ctx),
|
|
1872
2360
|
// private from filters
|
|
1873
|
-
traverseQueryFilters(visitor$2,
|
|
2361
|
+
traverseQueryFilters(visitor$2, ctx)
|
|
1874
2362
|
// we allow empty objects to validate and only sanitize them out, so that users may write "lazy" queries without checking their params exist
|
|
1875
2363
|
)(filters2);
|
|
1876
2364
|
});
|
|
1877
|
-
const defaultValidateSort = curry((
|
|
1878
|
-
if (!schema) {
|
|
2365
|
+
const defaultValidateSort = curry((ctx, sort2) => {
|
|
2366
|
+
if (!ctx.schema) {
|
|
1879
2367
|
throw new Error("Missing schema in defaultValidateSort");
|
|
1880
2368
|
}
|
|
1881
2369
|
return pipe(
|
|
1882
2370
|
// non attribute keys
|
|
1883
|
-
traverseQuerySort(
|
|
1884
|
-
(
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
},
|
|
1892
|
-
{ schema }
|
|
1893
|
-
),
|
|
2371
|
+
traverseQuerySort(({ key, attribute, path }) => {
|
|
2372
|
+
if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
|
|
2373
|
+
return;
|
|
2374
|
+
}
|
|
2375
|
+
if (!attribute) {
|
|
2376
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
2377
|
+
}
|
|
2378
|
+
}, ctx),
|
|
1894
2379
|
// dynamic zones from sort
|
|
1895
|
-
traverseQuerySort(visitor,
|
|
2380
|
+
traverseQuerySort(visitor, ctx),
|
|
1896
2381
|
// morphTo relations from sort
|
|
1897
|
-
traverseQuerySort(visitor$1,
|
|
2382
|
+
traverseQuerySort(visitor$1, ctx),
|
|
1898
2383
|
// private from sort
|
|
1899
|
-
traverseQuerySort(visitor$2,
|
|
2384
|
+
traverseQuerySort(visitor$2, ctx),
|
|
1900
2385
|
// passwords from filters
|
|
1901
|
-
traverseQuerySort(visitor$3,
|
|
2386
|
+
traverseQuerySort(visitor$3, ctx),
|
|
1902
2387
|
// keys for empty non-scalar values
|
|
1903
|
-
traverseQuerySort(
|
|
1904
|
-
(
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
},
|
|
1912
|
-
{ schema }
|
|
1913
|
-
)
|
|
2388
|
+
traverseQuerySort(({ key, attribute, value, path }) => {
|
|
2389
|
+
if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
|
|
2390
|
+
return;
|
|
2391
|
+
}
|
|
2392
|
+
if (!isScalarAttribute(attribute) && isEmpty(value)) {
|
|
2393
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
2394
|
+
}
|
|
2395
|
+
}, ctx)
|
|
1914
2396
|
)(sort2);
|
|
1915
2397
|
});
|
|
1916
|
-
const defaultValidateFields = curry((
|
|
1917
|
-
if (!schema) {
|
|
2398
|
+
const defaultValidateFields = curry((ctx, fields2) => {
|
|
2399
|
+
if (!ctx.schema) {
|
|
1918
2400
|
throw new Error("Missing schema in defaultValidateFields");
|
|
1919
2401
|
}
|
|
1920
2402
|
return pipe(
|
|
1921
2403
|
// Only allow scalar attributes
|
|
1922
|
-
traverseQueryFields(
|
|
1923
|
-
(
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
},
|
|
1931
|
-
{ schema }
|
|
1932
|
-
),
|
|
2404
|
+
traverseQueryFields(({ key, attribute, path }) => {
|
|
2405
|
+
if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
|
|
2406
|
+
return;
|
|
2407
|
+
}
|
|
2408
|
+
if (isNil(attribute) || !isScalarAttribute(attribute)) {
|
|
2409
|
+
throwInvalidKey({ key, path: path.attribute });
|
|
2410
|
+
}
|
|
2411
|
+
}, ctx),
|
|
1933
2412
|
// private fields
|
|
1934
|
-
traverseQueryFields(visitor$2,
|
|
2413
|
+
traverseQueryFields(visitor$2, ctx),
|
|
1935
2414
|
// password fields
|
|
1936
|
-
traverseQueryFields(visitor$3,
|
|
2415
|
+
traverseQueryFields(visitor$3, ctx)
|
|
1937
2416
|
)(fields2);
|
|
1938
2417
|
});
|
|
1939
|
-
const defaultValidatePopulate = curry((
|
|
1940
|
-
if (!schema) {
|
|
2418
|
+
const defaultValidatePopulate = curry((ctx, populate2) => {
|
|
2419
|
+
if (!ctx.schema) {
|
|
1941
2420
|
throw new Error("Missing schema in defaultValidatePopulate");
|
|
1942
2421
|
}
|
|
1943
2422
|
return pipe(
|
|
1944
|
-
traverseQueryPopulate(
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
2423
|
+
traverseQueryPopulate(async ({ key, value, schema, attribute, getModel }, { set }) => {
|
|
2424
|
+
if (attribute) {
|
|
2425
|
+
return;
|
|
2426
|
+
}
|
|
2427
|
+
if (key === "sort") {
|
|
2428
|
+
set(
|
|
2429
|
+
key,
|
|
2430
|
+
await defaultValidateSort(
|
|
2431
|
+
{
|
|
2432
|
+
schema,
|
|
2433
|
+
getModel
|
|
2434
|
+
},
|
|
2435
|
+
value
|
|
2436
|
+
)
|
|
2437
|
+
);
|
|
2438
|
+
}
|
|
2439
|
+
if (key === "filters") {
|
|
2440
|
+
set(
|
|
2441
|
+
key,
|
|
2442
|
+
await defaultValidateFilters(
|
|
2443
|
+
{
|
|
2444
|
+
schema,
|
|
2445
|
+
getModel
|
|
2446
|
+
},
|
|
2447
|
+
value
|
|
2448
|
+
)
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
if (key === "fields") {
|
|
2452
|
+
set(
|
|
2453
|
+
key,
|
|
2454
|
+
await defaultValidateFields(
|
|
2455
|
+
{
|
|
2456
|
+
schema,
|
|
2457
|
+
getModel
|
|
2458
|
+
},
|
|
2459
|
+
value
|
|
2460
|
+
)
|
|
2461
|
+
);
|
|
2462
|
+
}
|
|
2463
|
+
if (key === "populate") {
|
|
2464
|
+
set(
|
|
2465
|
+
key,
|
|
2466
|
+
await defaultValidatePopulate(
|
|
2467
|
+
{
|
|
2468
|
+
schema,
|
|
2469
|
+
getModel
|
|
2470
|
+
},
|
|
2471
|
+
value
|
|
2472
|
+
)
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
}, ctx),
|
|
1964
2476
|
// Remove private fields
|
|
1965
|
-
traverseQueryPopulate(visitor$2,
|
|
2477
|
+
traverseQueryPopulate(visitor$2, ctx)
|
|
1966
2478
|
)(populate2);
|
|
1967
2479
|
});
|
|
1968
2480
|
const validators = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -1973,8 +2485,9 @@ const validators = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
1973
2485
|
defaultValidateSort,
|
|
1974
2486
|
throwPasswords
|
|
1975
2487
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1976
|
-
const { ID_ATTRIBUTE
|
|
1977
|
-
const
|
|
2488
|
+
const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants$1;
|
|
2489
|
+
const createAPIValidators = (opts) => {
|
|
2490
|
+
const { getModel } = opts || {};
|
|
1978
2491
|
const validateInput = async (data, schema, { auth } = {}) => {
|
|
1979
2492
|
if (!schema) {
|
|
1980
2493
|
throw new Error("Missing schema in validateInput");
|
|
@@ -1987,22 +2500,37 @@ const createContentAPIValidators = () => {
|
|
|
1987
2500
|
const transforms = [
|
|
1988
2501
|
(data2) => {
|
|
1989
2502
|
if (isObject(data2)) {
|
|
1990
|
-
if (ID_ATTRIBUTE
|
|
1991
|
-
|
|
2503
|
+
if (ID_ATTRIBUTE in data2) {
|
|
2504
|
+
throwInvalidKey({ key: ID_ATTRIBUTE });
|
|
1992
2505
|
}
|
|
1993
|
-
if (DOC_ID_ATTRIBUTE
|
|
1994
|
-
|
|
2506
|
+
if (DOC_ID_ATTRIBUTE in data2) {
|
|
2507
|
+
throwInvalidKey({ key: DOC_ID_ATTRIBUTE });
|
|
1995
2508
|
}
|
|
1996
2509
|
}
|
|
2510
|
+
return data2;
|
|
1997
2511
|
},
|
|
1998
2512
|
// non-writable attributes
|
|
1999
|
-
traverseEntity$1(throwRestrictedFields(nonWritableAttributes), { schema })
|
|
2513
|
+
traverseEntity$1(throwRestrictedFields(nonWritableAttributes), { schema, getModel }),
|
|
2514
|
+
// unrecognized attributes
|
|
2515
|
+
traverseEntity$1(throwUnrecognizedFields, { schema, getModel })
|
|
2000
2516
|
];
|
|
2001
2517
|
if (auth) {
|
|
2002
|
-
transforms.push(
|
|
2518
|
+
transforms.push(
|
|
2519
|
+
traverseEntity$1(throwRestrictedRelations(auth), {
|
|
2520
|
+
schema,
|
|
2521
|
+
getModel
|
|
2522
|
+
})
|
|
2523
|
+
);
|
|
2524
|
+
}
|
|
2525
|
+
opts?.validators?.input?.forEach((validator) => transforms.push(validator(schema)));
|
|
2526
|
+
try {
|
|
2527
|
+
await pipe(...transforms)(data);
|
|
2528
|
+
} catch (e) {
|
|
2529
|
+
if (e instanceof ValidationError) {
|
|
2530
|
+
e.details.source = "body";
|
|
2531
|
+
}
|
|
2532
|
+
throw e;
|
|
2003
2533
|
}
|
|
2004
|
-
strapi.validators.get("content-api.input").forEach((validator) => transforms.push(validator(schema)));
|
|
2005
|
-
await pipe(...transforms)(data);
|
|
2006
2534
|
};
|
|
2007
2535
|
const validateQuery = async (query, schema, { auth } = {}) => {
|
|
2008
2536
|
if (!schema) {
|
|
@@ -2030,38 +2558,85 @@ const createContentAPIValidators = () => {
|
|
|
2030
2558
|
await Promise.all(filters2.map((filter) => validateFilters(filter, schema, { auth })));
|
|
2031
2559
|
return;
|
|
2032
2560
|
}
|
|
2033
|
-
const transforms = [defaultValidateFilters(schema)];
|
|
2561
|
+
const transforms = [defaultValidateFilters({ schema, getModel })];
|
|
2034
2562
|
if (auth) {
|
|
2035
|
-
transforms.push(
|
|
2563
|
+
transforms.push(
|
|
2564
|
+
traverseQueryFilters(throwRestrictedRelations(auth), {
|
|
2565
|
+
schema,
|
|
2566
|
+
getModel
|
|
2567
|
+
})
|
|
2568
|
+
);
|
|
2569
|
+
}
|
|
2570
|
+
try {
|
|
2571
|
+
await pipe(...transforms)(filters2);
|
|
2572
|
+
} catch (e) {
|
|
2573
|
+
if (e instanceof ValidationError) {
|
|
2574
|
+
e.details.source = "query";
|
|
2575
|
+
e.details.param = "filters";
|
|
2576
|
+
}
|
|
2577
|
+
throw e;
|
|
2036
2578
|
}
|
|
2037
|
-
await pipe(...transforms)(filters2);
|
|
2038
2579
|
};
|
|
2039
2580
|
const validateSort = async (sort2, schema, { auth } = {}) => {
|
|
2040
2581
|
if (!schema) {
|
|
2041
2582
|
throw new Error("Missing schema in validateSort");
|
|
2042
2583
|
}
|
|
2043
|
-
const transforms = [defaultValidateSort(schema)];
|
|
2584
|
+
const transforms = [defaultValidateSort({ schema, getModel })];
|
|
2044
2585
|
if (auth) {
|
|
2045
|
-
transforms.push(
|
|
2586
|
+
transforms.push(
|
|
2587
|
+
traverseQuerySort(throwRestrictedRelations(auth), {
|
|
2588
|
+
schema,
|
|
2589
|
+
getModel
|
|
2590
|
+
})
|
|
2591
|
+
);
|
|
2592
|
+
}
|
|
2593
|
+
try {
|
|
2594
|
+
await pipe(...transforms)(sort2);
|
|
2595
|
+
} catch (e) {
|
|
2596
|
+
if (e instanceof ValidationError) {
|
|
2597
|
+
e.details.source = "query";
|
|
2598
|
+
e.details.param = "sort";
|
|
2599
|
+
}
|
|
2600
|
+
throw e;
|
|
2046
2601
|
}
|
|
2047
|
-
await pipe(...transforms)(sort2);
|
|
2048
2602
|
};
|
|
2049
2603
|
const validateFields = async (fields2, schema) => {
|
|
2050
2604
|
if (!schema) {
|
|
2051
2605
|
throw new Error("Missing schema in validateFields");
|
|
2052
2606
|
}
|
|
2053
|
-
const transforms = [defaultValidateFields(schema)];
|
|
2054
|
-
|
|
2607
|
+
const transforms = [defaultValidateFields({ schema, getModel })];
|
|
2608
|
+
try {
|
|
2609
|
+
await pipe(...transforms)(fields2);
|
|
2610
|
+
} catch (e) {
|
|
2611
|
+
if (e instanceof ValidationError) {
|
|
2612
|
+
e.details.source = "query";
|
|
2613
|
+
e.details.param = "fields";
|
|
2614
|
+
}
|
|
2615
|
+
throw e;
|
|
2616
|
+
}
|
|
2055
2617
|
};
|
|
2056
2618
|
const validatePopulate = async (populate2, schema, { auth } = {}) => {
|
|
2057
2619
|
if (!schema) {
|
|
2058
2620
|
throw new Error("Missing schema in sanitizePopulate");
|
|
2059
2621
|
}
|
|
2060
|
-
const transforms = [defaultValidatePopulate(schema)];
|
|
2622
|
+
const transforms = [defaultValidatePopulate({ schema, getModel })];
|
|
2061
2623
|
if (auth) {
|
|
2062
|
-
transforms.push(
|
|
2624
|
+
transforms.push(
|
|
2625
|
+
traverseQueryPopulate(throwRestrictedRelations(auth), {
|
|
2626
|
+
schema,
|
|
2627
|
+
getModel
|
|
2628
|
+
})
|
|
2629
|
+
);
|
|
2630
|
+
}
|
|
2631
|
+
try {
|
|
2632
|
+
await pipe(...transforms)(populate2);
|
|
2633
|
+
} catch (e) {
|
|
2634
|
+
if (e instanceof ValidationError) {
|
|
2635
|
+
e.details.source = "query";
|
|
2636
|
+
e.details.param = "populate";
|
|
2637
|
+
}
|
|
2638
|
+
throw e;
|
|
2063
2639
|
}
|
|
2064
|
-
await pipe(...transforms)(populate2);
|
|
2065
2640
|
};
|
|
2066
2641
|
return {
|
|
2067
2642
|
input: validateInput,
|
|
@@ -2072,436 +2647,12 @@ const createContentAPIValidators = () => {
|
|
|
2072
2647
|
populate: validatePopulate
|
|
2073
2648
|
};
|
|
2074
2649
|
};
|
|
2075
|
-
const
|
|
2076
|
-
|
|
2077
|
-
|
|
2650
|
+
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2651
|
+
__proto__: null,
|
|
2652
|
+
createAPIValidators,
|
|
2078
2653
|
validators,
|
|
2079
|
-
visitors
|
|
2080
|
-
};
|
|
2081
|
-
const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, PUBLISHED_AT_ATTRIBUTE } = constants$1;
|
|
2082
|
-
class InvalidOrderError extends Error {
|
|
2083
|
-
constructor() {
|
|
2084
|
-
super();
|
|
2085
|
-
this.message = "Invalid order. order can only be one of asc|desc|ASC|DESC";
|
|
2086
|
-
}
|
|
2087
|
-
}
|
|
2088
|
-
class InvalidSortError extends Error {
|
|
2089
|
-
constructor() {
|
|
2090
|
-
super();
|
|
2091
|
-
this.message = "Invalid sort parameter. Expected a string, an array of strings, a sort object or an array of sort objects";
|
|
2092
|
-
}
|
|
2093
|
-
}
|
|
2094
|
-
function validateOrder(order) {
|
|
2095
|
-
if (!isString(order) || !["asc", "desc"].includes(order.toLocaleLowerCase())) {
|
|
2096
|
-
throw new InvalidOrderError();
|
|
2097
|
-
}
|
|
2098
|
-
}
|
|
2099
|
-
const convertCountQueryParams = (countQuery) => {
|
|
2100
|
-
return parseType({ type: "boolean", value: countQuery });
|
|
2101
|
-
};
|
|
2102
|
-
const convertOrderingQueryParams = (ordering) => {
|
|
2103
|
-
return ordering;
|
|
2104
|
-
};
|
|
2105
|
-
const isPlainObject = (value) => _$1.isPlainObject(value);
|
|
2106
|
-
const isStringArray = (value) => isArray(value) && value.every(isString);
|
|
2107
|
-
const convertSortQueryParams = (sortQuery) => {
|
|
2108
|
-
if (typeof sortQuery === "string") {
|
|
2109
|
-
return convertStringSortQueryParam(sortQuery);
|
|
2110
|
-
}
|
|
2111
|
-
if (isStringArray(sortQuery)) {
|
|
2112
|
-
return sortQuery.flatMap((sortValue) => convertStringSortQueryParam(sortValue));
|
|
2113
|
-
}
|
|
2114
|
-
if (Array.isArray(sortQuery)) {
|
|
2115
|
-
return sortQuery.map((sortValue) => convertNestedSortQueryParam(sortValue));
|
|
2116
|
-
}
|
|
2117
|
-
if (isPlainObject(sortQuery)) {
|
|
2118
|
-
return convertNestedSortQueryParam(sortQuery);
|
|
2119
|
-
}
|
|
2120
|
-
throw new InvalidSortError();
|
|
2121
|
-
};
|
|
2122
|
-
const convertStringSortQueryParam = (sortQuery) => {
|
|
2123
|
-
return sortQuery.split(",").map((value) => convertSingleSortQueryParam(value));
|
|
2124
|
-
};
|
|
2125
|
-
const convertSingleSortQueryParam = (sortQuery) => {
|
|
2126
|
-
if (!sortQuery) {
|
|
2127
|
-
return {};
|
|
2128
|
-
}
|
|
2129
|
-
if (!isString(sortQuery)) {
|
|
2130
|
-
throw new Error("Invalid sort query");
|
|
2131
|
-
}
|
|
2132
|
-
const [field, order = "asc"] = sortQuery.split(":");
|
|
2133
|
-
if (field.length === 0) {
|
|
2134
|
-
throw new Error("Field cannot be empty");
|
|
2135
|
-
}
|
|
2136
|
-
validateOrder(order);
|
|
2137
|
-
return _$1.set({}, field, order);
|
|
2138
|
-
};
|
|
2139
|
-
const convertNestedSortQueryParam = (sortQuery) => {
|
|
2140
|
-
const transformedSort = {};
|
|
2141
|
-
for (const field of Object.keys(sortQuery)) {
|
|
2142
|
-
const order = sortQuery[field];
|
|
2143
|
-
if (isPlainObject(order)) {
|
|
2144
|
-
transformedSort[field] = convertNestedSortQueryParam(order);
|
|
2145
|
-
} else if (typeof order === "string") {
|
|
2146
|
-
validateOrder(order);
|
|
2147
|
-
transformedSort[field] = order;
|
|
2148
|
-
} else {
|
|
2149
|
-
throw Error(`Invalid sort type expected object or string got ${typeof order}`);
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2152
|
-
return transformedSort;
|
|
2153
|
-
};
|
|
2154
|
-
const convertStartQueryParams = (startQuery) => {
|
|
2155
|
-
const startAsANumber = _$1.toNumber(startQuery);
|
|
2156
|
-
if (!_$1.isInteger(startAsANumber) || startAsANumber < 0) {
|
|
2157
|
-
throw new Error(`convertStartQueryParams expected a positive integer got ${startAsANumber}`);
|
|
2158
|
-
}
|
|
2159
|
-
return startAsANumber;
|
|
2160
|
-
};
|
|
2161
|
-
const convertLimitQueryParams = (limitQuery) => {
|
|
2162
|
-
const limitAsANumber = _$1.toNumber(limitQuery);
|
|
2163
|
-
if (!_$1.isInteger(limitAsANumber) || limitAsANumber !== -1 && limitAsANumber < 0) {
|
|
2164
|
-
throw new Error(`convertLimitQueryParams expected a positive integer got ${limitAsANumber}`);
|
|
2165
|
-
}
|
|
2166
|
-
if (limitAsANumber === -1) {
|
|
2167
|
-
return void 0;
|
|
2168
|
-
}
|
|
2169
|
-
return limitAsANumber;
|
|
2170
|
-
};
|
|
2171
|
-
const convertPageQueryParams = (page) => {
|
|
2172
|
-
const pageVal = toNumber(page);
|
|
2173
|
-
if (!isInteger(pageVal) || pageVal <= 0) {
|
|
2174
|
-
throw new PaginationError(
|
|
2175
|
-
`Invalid 'page' parameter. Expected an integer > 0, received: ${page}`
|
|
2176
|
-
);
|
|
2177
|
-
}
|
|
2178
|
-
return pageVal;
|
|
2179
|
-
};
|
|
2180
|
-
const convertPageSizeQueryParams = (pageSize, page) => {
|
|
2181
|
-
const pageSizeVal = toNumber(pageSize);
|
|
2182
|
-
if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {
|
|
2183
|
-
throw new PaginationError(
|
|
2184
|
-
`Invalid 'pageSize' parameter. Expected an integer > 0, received: ${page}`
|
|
2185
|
-
);
|
|
2186
|
-
}
|
|
2187
|
-
return pageSizeVal;
|
|
2188
|
-
};
|
|
2189
|
-
const validatePaginationParams = (page, pageSize, start, limit) => {
|
|
2190
|
-
const isPagePagination = !isNil(page) || !isNil(pageSize);
|
|
2191
|
-
const isOffsetPagination = !isNil(start) || !isNil(limit);
|
|
2192
|
-
if (isPagePagination && isOffsetPagination) {
|
|
2193
|
-
throw new PaginationError(
|
|
2194
|
-
"Invalid pagination attributes. You cannot use page and offset pagination in the same query"
|
|
2195
|
-
);
|
|
2196
|
-
}
|
|
2197
|
-
};
|
|
2198
|
-
class InvalidPopulateError extends Error {
|
|
2199
|
-
constructor() {
|
|
2200
|
-
super();
|
|
2201
|
-
this.message = "Invalid populate parameter. Expected a string, an array of strings, a populate object";
|
|
2202
|
-
}
|
|
2203
|
-
}
|
|
2204
|
-
const convertPopulateQueryParams = (populate2, schema, depth = 0) => {
|
|
2205
|
-
if (depth === 0 && populate2 === "*") {
|
|
2206
|
-
return true;
|
|
2207
|
-
}
|
|
2208
|
-
if (typeof populate2 === "string") {
|
|
2209
|
-
return populate2.split(",").map((value) => _$1.trim(value));
|
|
2210
|
-
}
|
|
2211
|
-
if (Array.isArray(populate2)) {
|
|
2212
|
-
return _$1.uniq(
|
|
2213
|
-
populate2.flatMap((value) => {
|
|
2214
|
-
if (typeof value !== "string") {
|
|
2215
|
-
throw new InvalidPopulateError();
|
|
2216
|
-
}
|
|
2217
|
-
return value.split(",").map((value2) => _$1.trim(value2));
|
|
2218
|
-
})
|
|
2219
|
-
);
|
|
2220
|
-
}
|
|
2221
|
-
if (_$1.isPlainObject(populate2)) {
|
|
2222
|
-
return convertPopulateObject(populate2, schema);
|
|
2223
|
-
}
|
|
2224
|
-
throw new InvalidPopulateError();
|
|
2225
|
-
};
|
|
2226
|
-
const hasFragmentPopulateDefined = (populate2) => {
|
|
2227
|
-
return typeof populate2 === "object" && "on" in populate2 && !isNil(populate2.on);
|
|
2228
|
-
};
|
|
2229
|
-
const convertPopulateObject = (populate2, schema) => {
|
|
2230
|
-
if (!schema) {
|
|
2231
|
-
return {};
|
|
2232
|
-
}
|
|
2233
|
-
const { attributes } = schema;
|
|
2234
|
-
return Object.entries(populate2).reduce((acc, [key, subPopulate]) => {
|
|
2235
|
-
if (_$1.isBoolean(subPopulate)) {
|
|
2236
|
-
return { ...acc, [key]: subPopulate };
|
|
2237
|
-
}
|
|
2238
|
-
const attribute = attributes[key];
|
|
2239
|
-
if (!attribute) {
|
|
2240
|
-
return acc;
|
|
2241
|
-
}
|
|
2242
|
-
const isAllowedAttributeForFragmentPopulate = isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);
|
|
2243
|
-
if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined(subPopulate)) {
|
|
2244
|
-
return {
|
|
2245
|
-
...acc,
|
|
2246
|
-
[key]: {
|
|
2247
|
-
on: Object.entries(subPopulate.on).reduce(
|
|
2248
|
-
(acc2, [type, typeSubPopulate]) => ({
|
|
2249
|
-
...acc2,
|
|
2250
|
-
[type]: convertNestedPopulate(typeSubPopulate, strapi.getModel(type))
|
|
2251
|
-
}),
|
|
2252
|
-
{}
|
|
2253
|
-
)
|
|
2254
|
-
}
|
|
2255
|
-
};
|
|
2256
|
-
}
|
|
2257
|
-
if (isDynamicZoneAttribute(attribute)) {
|
|
2258
|
-
const populates = attribute.components.map((uid) => strapi.getModel(uid)).map((schema2) => convertNestedPopulate(subPopulate, schema2)).map((populate22) => populate22 === true ? {} : populate22).filter((populate22) => populate22 !== false);
|
|
2259
|
-
if (isEmpty(populates)) {
|
|
2260
|
-
return acc;
|
|
2261
|
-
}
|
|
2262
|
-
return {
|
|
2263
|
-
...acc,
|
|
2264
|
-
[key]: mergeAll(populates)
|
|
2265
|
-
};
|
|
2266
|
-
}
|
|
2267
|
-
if (isMorphToRelationalAttribute(attribute)) {
|
|
2268
|
-
return { ...acc, [key]: convertNestedPopulate(subPopulate, void 0) };
|
|
2269
|
-
}
|
|
2270
|
-
let targetSchemaUID;
|
|
2271
|
-
if (attribute.type === "relation") {
|
|
2272
|
-
targetSchemaUID = attribute.target;
|
|
2273
|
-
} else if (attribute.type === "component") {
|
|
2274
|
-
targetSchemaUID = attribute.component;
|
|
2275
|
-
} else if (attribute.type === "media") {
|
|
2276
|
-
targetSchemaUID = "plugin::upload.file";
|
|
2277
|
-
} else {
|
|
2278
|
-
return acc;
|
|
2279
|
-
}
|
|
2280
|
-
const targetSchema = strapi.getModel(targetSchemaUID);
|
|
2281
|
-
if (!targetSchema) {
|
|
2282
|
-
return acc;
|
|
2283
|
-
}
|
|
2284
|
-
const populateObject = convertNestedPopulate(subPopulate, targetSchema);
|
|
2285
|
-
if (!populateObject) {
|
|
2286
|
-
return acc;
|
|
2287
|
-
}
|
|
2288
|
-
return {
|
|
2289
|
-
...acc,
|
|
2290
|
-
[key]: populateObject
|
|
2291
|
-
};
|
|
2292
|
-
}, {});
|
|
2293
|
-
};
|
|
2294
|
-
const convertNestedPopulate = (subPopulate, schema) => {
|
|
2295
|
-
if (_$1.isString(subPopulate)) {
|
|
2296
|
-
return parseType({ type: "boolean", value: subPopulate, forceCast: true });
|
|
2297
|
-
}
|
|
2298
|
-
if (_$1.isBoolean(subPopulate)) {
|
|
2299
|
-
return subPopulate;
|
|
2300
|
-
}
|
|
2301
|
-
if (!isPlainObject(subPopulate)) {
|
|
2302
|
-
throw new Error(`Invalid nested populate. Expected '*' or an object`);
|
|
2303
|
-
}
|
|
2304
|
-
const { sort: sort2, filters: filters2, fields: fields2, populate: populate2, count, ordering, page, pageSize, start, limit } = subPopulate;
|
|
2305
|
-
const query = {};
|
|
2306
|
-
if (sort2) {
|
|
2307
|
-
query.orderBy = convertSortQueryParams(sort2);
|
|
2308
|
-
}
|
|
2309
|
-
if (filters2) {
|
|
2310
|
-
query.where = convertFiltersQueryParams(filters2, schema);
|
|
2311
|
-
}
|
|
2312
|
-
if (fields2) {
|
|
2313
|
-
query.select = convertFieldsQueryParams(fields2);
|
|
2314
|
-
}
|
|
2315
|
-
if (populate2) {
|
|
2316
|
-
query.populate = convertPopulateQueryParams(populate2, schema);
|
|
2317
|
-
}
|
|
2318
|
-
if (count) {
|
|
2319
|
-
query.count = convertCountQueryParams(count);
|
|
2320
|
-
}
|
|
2321
|
-
if (ordering) {
|
|
2322
|
-
query.ordering = convertOrderingQueryParams(ordering);
|
|
2323
|
-
}
|
|
2324
|
-
validatePaginationParams(page, pageSize, start, limit);
|
|
2325
|
-
if (!isNil(page)) {
|
|
2326
|
-
query.page = convertPageQueryParams(page);
|
|
2327
|
-
}
|
|
2328
|
-
if (!isNil(pageSize)) {
|
|
2329
|
-
query.pageSize = convertPageSizeQueryParams(pageSize, page);
|
|
2330
|
-
}
|
|
2331
|
-
if (!isNil(start)) {
|
|
2332
|
-
query.offset = convertStartQueryParams(start);
|
|
2333
|
-
}
|
|
2334
|
-
if (!isNil(limit)) {
|
|
2335
|
-
query.limit = convertLimitQueryParams(limit);
|
|
2336
|
-
}
|
|
2337
|
-
return query;
|
|
2338
|
-
};
|
|
2339
|
-
const convertFieldsQueryParams = (fields2, depth = 0) => {
|
|
2340
|
-
if (depth === 0 && fields2 === "*") {
|
|
2341
|
-
return void 0;
|
|
2342
|
-
}
|
|
2343
|
-
if (typeof fields2 === "string") {
|
|
2344
|
-
const fieldsValues = fields2.split(",").map((value) => _$1.trim(value));
|
|
2345
|
-
return _$1.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);
|
|
2346
|
-
}
|
|
2347
|
-
if (isStringArray(fields2)) {
|
|
2348
|
-
const fieldsValues = fields2.flatMap((value) => convertFieldsQueryParams(value, depth + 1)).filter((v) => !isNil(v));
|
|
2349
|
-
return _$1.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);
|
|
2350
|
-
}
|
|
2351
|
-
throw new Error("Invalid fields parameter. Expected a string or an array of strings");
|
|
2352
|
-
};
|
|
2353
|
-
const isValidSchemaAttribute = (key, schema) => {
|
|
2354
|
-
if ([DOC_ID_ATTRIBUTE, ID_ATTRIBUTE].includes(key)) {
|
|
2355
|
-
return true;
|
|
2356
|
-
}
|
|
2357
|
-
if (!schema) {
|
|
2358
|
-
return false;
|
|
2359
|
-
}
|
|
2360
|
-
return Object.keys(schema.attributes).includes(key);
|
|
2361
|
-
};
|
|
2362
|
-
const convertFiltersQueryParams = (filters2, schema) => {
|
|
2363
|
-
if (!isObject(filters2)) {
|
|
2364
|
-
throw new Error("The filters parameter must be an object or an array");
|
|
2365
|
-
}
|
|
2366
|
-
const filtersCopy = cloneDeep(filters2);
|
|
2367
|
-
return convertAndSanitizeFilters(filtersCopy, schema);
|
|
2368
|
-
};
|
|
2369
|
-
const convertAndSanitizeFilters = (filters2, schema) => {
|
|
2370
|
-
if (Array.isArray(filters2)) {
|
|
2371
|
-
return filters2.map((filter) => convertAndSanitizeFilters(filter, schema)).filter((filter) => !isPlainObject(filter) || !isEmpty(filter));
|
|
2372
|
-
}
|
|
2373
|
-
if (!isPlainObject(filters2)) {
|
|
2374
|
-
return filters2;
|
|
2375
|
-
}
|
|
2376
|
-
const removeOperator = (operator) => delete filters2[operator];
|
|
2377
|
-
for (const [key, value] of Object.entries(filters2)) {
|
|
2378
|
-
const attribute = get(key, schema?.attributes);
|
|
2379
|
-
const validKey = isOperator(key) || isValidSchemaAttribute(key, schema);
|
|
2380
|
-
if (!validKey) {
|
|
2381
|
-
removeOperator(key);
|
|
2382
|
-
} else if (attribute) {
|
|
2383
|
-
if (attribute.type === "relation") {
|
|
2384
|
-
filters2[key] = convertAndSanitizeFilters(value, strapi.getModel(attribute.target));
|
|
2385
|
-
} else if (attribute.type === "component") {
|
|
2386
|
-
filters2[key] = convertAndSanitizeFilters(value, strapi.getModel(attribute.component));
|
|
2387
|
-
} else if (attribute.type === "media") {
|
|
2388
|
-
filters2[key] = convertAndSanitizeFilters(value, strapi.getModel("plugin::upload.file"));
|
|
2389
|
-
} else if (attribute.type === "dynamiczone") {
|
|
2390
|
-
removeOperator(key);
|
|
2391
|
-
} else if (attribute.type === "password") {
|
|
2392
|
-
removeOperator(key);
|
|
2393
|
-
} else {
|
|
2394
|
-
filters2[key] = convertAndSanitizeFilters(value, schema);
|
|
2395
|
-
}
|
|
2396
|
-
} else if (["$null", "$notNull"].includes(key)) {
|
|
2397
|
-
filters2[key] = parseType({ type: "boolean", value: filters2[key], forceCast: true });
|
|
2398
|
-
} else if (isObject(value)) {
|
|
2399
|
-
filters2[key] = convertAndSanitizeFilters(value, schema);
|
|
2400
|
-
}
|
|
2401
|
-
if (isPlainObject(filters2[key]) && isEmpty(filters2[key])) {
|
|
2402
|
-
removeOperator(key);
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
return filters2;
|
|
2406
|
-
};
|
|
2407
|
-
const convertStatusParams = (status, query = {}) => {
|
|
2408
|
-
query.filters = ({ meta }) => {
|
|
2409
|
-
const contentType = strapi.contentTypes[meta.uid];
|
|
2410
|
-
if (!contentType || !hasDraftAndPublish(contentType)) {
|
|
2411
|
-
return {};
|
|
2412
|
-
}
|
|
2413
|
-
return { [PUBLISHED_AT_ATTRIBUTE]: { $null: status === "draft" } };
|
|
2414
|
-
};
|
|
2415
|
-
};
|
|
2416
|
-
const transformParamsToQuery = (uid, params) => {
|
|
2417
|
-
const schema = strapi.getModel(uid);
|
|
2418
|
-
const query = {};
|
|
2419
|
-
const { _q, sort: sort2, filters: filters2, fields: fields2, populate: populate2, page, pageSize, start, limit, status, ...rest } = params;
|
|
2420
|
-
if (!isNil(status)) {
|
|
2421
|
-
convertStatusParams(status, query);
|
|
2422
|
-
}
|
|
2423
|
-
if (!isNil(_q)) {
|
|
2424
|
-
query._q = _q;
|
|
2425
|
-
}
|
|
2426
|
-
if (!isNil(sort2)) {
|
|
2427
|
-
query.orderBy = convertSortQueryParams(sort2);
|
|
2428
|
-
}
|
|
2429
|
-
if (!isNil(filters2)) {
|
|
2430
|
-
query.where = convertFiltersQueryParams(filters2, schema);
|
|
2431
|
-
}
|
|
2432
|
-
if (!isNil(fields2)) {
|
|
2433
|
-
query.select = convertFieldsQueryParams(fields2);
|
|
2434
|
-
}
|
|
2435
|
-
if (!isNil(populate2)) {
|
|
2436
|
-
query.populate = convertPopulateQueryParams(populate2, schema);
|
|
2437
|
-
}
|
|
2438
|
-
validatePaginationParams(page, pageSize, start, limit);
|
|
2439
|
-
if (!isNil(page)) {
|
|
2440
|
-
query.page = convertPageQueryParams(page);
|
|
2441
|
-
}
|
|
2442
|
-
if (!isNil(pageSize)) {
|
|
2443
|
-
query.pageSize = convertPageSizeQueryParams(pageSize, page);
|
|
2444
|
-
}
|
|
2445
|
-
if (!isNil(start)) {
|
|
2446
|
-
query.offset = convertStartQueryParams(start);
|
|
2447
|
-
}
|
|
2448
|
-
if (!isNil(limit)) {
|
|
2449
|
-
query.limit = convertLimitQueryParams(limit);
|
|
2450
|
-
}
|
|
2451
|
-
return {
|
|
2452
|
-
...rest,
|
|
2453
|
-
...query
|
|
2454
|
-
};
|
|
2455
|
-
};
|
|
2456
|
-
const convertQueryParams = {
|
|
2457
|
-
convertSortQueryParams,
|
|
2458
|
-
convertStartQueryParams,
|
|
2459
|
-
convertLimitQueryParams,
|
|
2460
|
-
convertPopulateQueryParams,
|
|
2461
|
-
convertFiltersQueryParams,
|
|
2462
|
-
convertFieldsQueryParams,
|
|
2463
|
-
transformParamsToQuery
|
|
2464
|
-
};
|
|
2465
|
-
function importDefault(modName) {
|
|
2466
|
-
const mod = require(modName);
|
|
2467
|
-
return mod && mod.__esModule ? mod.default : mod;
|
|
2468
|
-
}
|
|
2469
|
-
const machineId = () => {
|
|
2470
|
-
try {
|
|
2471
|
-
const deviceId = machineIdSync();
|
|
2472
|
-
return deviceId;
|
|
2473
|
-
} catch (error) {
|
|
2474
|
-
const deviceId = randomUUID();
|
|
2475
|
-
return deviceId;
|
|
2476
|
-
}
|
|
2477
|
-
};
|
|
2478
|
-
const handleYupError = (error, errorMessage) => {
|
|
2479
|
-
throw new YupValidationError(error, errorMessage);
|
|
2480
|
-
};
|
|
2481
|
-
const defaultValidationParam = { strict: true, abortEarly: false };
|
|
2482
|
-
const validateYupSchema = (schema, options = {}) => async (body, errorMessage) => {
|
|
2483
|
-
try {
|
|
2484
|
-
const optionsWithDefaults = defaults(defaultValidationParam, options);
|
|
2485
|
-
const result = await schema.validate(body, optionsWithDefaults);
|
|
2486
|
-
return result;
|
|
2487
|
-
} catch (e) {
|
|
2488
|
-
if (e instanceof yup$1.ValidationError) {
|
|
2489
|
-
handleYupError(e, errorMessage);
|
|
2490
|
-
}
|
|
2491
|
-
throw e;
|
|
2492
|
-
}
|
|
2493
|
-
};
|
|
2494
|
-
const validateYupSchemaSync = (schema, options = {}) => (body, errorMessage) => {
|
|
2495
|
-
try {
|
|
2496
|
-
const optionsWithDefaults = defaults(defaultValidationParam, options);
|
|
2497
|
-
return schema.validateSync(body, optionsWithDefaults);
|
|
2498
|
-
} catch (e) {
|
|
2499
|
-
if (e instanceof yup$1.ValidationError) {
|
|
2500
|
-
handleYupError(e, errorMessage);
|
|
2501
|
-
}
|
|
2502
|
-
throw e;
|
|
2503
|
-
}
|
|
2504
|
-
};
|
|
2654
|
+
visitors: index$1
|
|
2655
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2505
2656
|
const STRAPI_DEFAULTS = {
|
|
2506
2657
|
offset: {
|
|
2507
2658
|
start: 0,
|
|
@@ -2569,8 +2720,57 @@ const withDefaultPagination = (args, { defaults: defaults2 = {}, maxLimit = -1 }
|
|
|
2569
2720
|
);
|
|
2570
2721
|
return replacePaginationAttributes(args);
|
|
2571
2722
|
};
|
|
2723
|
+
const transformPagedPaginationInfo = (paginationInfo, total) => {
|
|
2724
|
+
if (!isNil(paginationInfo.page)) {
|
|
2725
|
+
const page = paginationInfo.page;
|
|
2726
|
+
const pageSize = paginationInfo.pageSize ?? total;
|
|
2727
|
+
return {
|
|
2728
|
+
page,
|
|
2729
|
+
pageSize,
|
|
2730
|
+
pageCount: pageSize > 0 ? Math.ceil(total / pageSize) : 0,
|
|
2731
|
+
total
|
|
2732
|
+
};
|
|
2733
|
+
}
|
|
2734
|
+
if (!isNil(paginationInfo.start)) {
|
|
2735
|
+
const start = paginationInfo.start;
|
|
2736
|
+
const limit = paginationInfo.limit ?? total;
|
|
2737
|
+
return {
|
|
2738
|
+
page: Math.floor(start / limit) + 1,
|
|
2739
|
+
pageSize: limit,
|
|
2740
|
+
pageCount: limit > 0 ? Math.ceil(total / limit) : 0,
|
|
2741
|
+
total
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
return {
|
|
2745
|
+
...paginationInfo,
|
|
2746
|
+
page: 1,
|
|
2747
|
+
pageSize: 10,
|
|
2748
|
+
pageCount: 1,
|
|
2749
|
+
total
|
|
2750
|
+
};
|
|
2751
|
+
};
|
|
2752
|
+
const transformOffsetPaginationInfo = (paginationInfo, total) => {
|
|
2753
|
+
if (!isNil(paginationInfo.page)) {
|
|
2754
|
+
const limit = paginationInfo.pageSize ?? total;
|
|
2755
|
+
const start = (paginationInfo.page - 1) * limit;
|
|
2756
|
+
return { start, limit, total };
|
|
2757
|
+
}
|
|
2758
|
+
if (!isNil(paginationInfo.start)) {
|
|
2759
|
+
const start = paginationInfo.start;
|
|
2760
|
+
const limit = paginationInfo.limit ?? total;
|
|
2761
|
+
return { start, limit, total };
|
|
2762
|
+
}
|
|
2763
|
+
return {
|
|
2764
|
+
...paginationInfo,
|
|
2765
|
+
start: 0,
|
|
2766
|
+
limit: 10,
|
|
2767
|
+
total
|
|
2768
|
+
};
|
|
2769
|
+
};
|
|
2572
2770
|
const pagination = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2573
2771
|
__proto__: null,
|
|
2772
|
+
transformOffsetPaginationInfo,
|
|
2773
|
+
transformPagedPaginationInfo,
|
|
2574
2774
|
withDefaultPagination
|
|
2575
2775
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2576
2776
|
const SUPPORTED_PACKAGE_MANAGERS = ["npm", "yarn"];
|
|
@@ -2653,72 +2853,6 @@ const file = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
|
|
|
2653
2853
|
streamToBuffer,
|
|
2654
2854
|
writableDiscardStream
|
|
2655
2855
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2656
|
-
const PLUGIN_PREFIX = "plugin::";
|
|
2657
|
-
const API_PREFIX = "api::";
|
|
2658
|
-
const parsePolicy = (policy2) => {
|
|
2659
|
-
if (typeof policy2 === "string") {
|
|
2660
|
-
return { policyName: policy2, config: {} };
|
|
2661
|
-
}
|
|
2662
|
-
const { name, config } = policy2;
|
|
2663
|
-
return { policyName: name, config };
|
|
2664
|
-
};
|
|
2665
|
-
const searchLocalPolicy = (policyName, policyContext) => {
|
|
2666
|
-
const { pluginName, apiName } = policyContext ?? {};
|
|
2667
|
-
if (pluginName) {
|
|
2668
|
-
return strapi.policy(`${PLUGIN_PREFIX}${pluginName}.${policyName}`);
|
|
2669
|
-
}
|
|
2670
|
-
if (apiName) {
|
|
2671
|
-
return strapi.policy(`${API_PREFIX}${apiName}.${policyName}`);
|
|
2672
|
-
}
|
|
2673
|
-
};
|
|
2674
|
-
const globalPolicy = ({ method, endpoint, controller, action, plugin }) => {
|
|
2675
|
-
return async (ctx, next) => {
|
|
2676
|
-
ctx.request.route = {
|
|
2677
|
-
endpoint: `${method} ${endpoint}`,
|
|
2678
|
-
controller: _$1.toLower(controller),
|
|
2679
|
-
action: _$1.toLower(action),
|
|
2680
|
-
verb: _$1.toLower(method),
|
|
2681
|
-
plugin
|
|
2682
|
-
};
|
|
2683
|
-
await next();
|
|
2684
|
-
};
|
|
2685
|
-
};
|
|
2686
|
-
const resolvePolicies = (config, policyContext) => {
|
|
2687
|
-
const { pluginName, apiName } = policyContext ?? {};
|
|
2688
|
-
return config.map((policyConfig) => {
|
|
2689
|
-
return {
|
|
2690
|
-
handler: getPolicy(policyConfig, { pluginName, apiName }),
|
|
2691
|
-
config: typeof policyConfig === "object" && policyConfig.config || {}
|
|
2692
|
-
};
|
|
2693
|
-
});
|
|
2694
|
-
};
|
|
2695
|
-
const findPolicy = (name, policyContext) => {
|
|
2696
|
-
const { pluginName, apiName } = policyContext ?? {};
|
|
2697
|
-
const resolvedPolicy = strapi.policy(name);
|
|
2698
|
-
if (resolvedPolicy !== void 0) {
|
|
2699
|
-
return resolvedPolicy;
|
|
2700
|
-
}
|
|
2701
|
-
const localPolicy = searchLocalPolicy(name, { pluginName, apiName });
|
|
2702
|
-
if (localPolicy !== void 0) {
|
|
2703
|
-
return localPolicy;
|
|
2704
|
-
}
|
|
2705
|
-
throw new Error(`Could not find policy "${name}"`);
|
|
2706
|
-
};
|
|
2707
|
-
const getPolicy = (policyConfig, policyContext) => {
|
|
2708
|
-
const { pluginName, apiName } = policyContext ?? {};
|
|
2709
|
-
if (typeof policyConfig === "function") {
|
|
2710
|
-
return policyConfig;
|
|
2711
|
-
}
|
|
2712
|
-
const { policyName, config } = parsePolicy(policyConfig);
|
|
2713
|
-
const policy2 = findPolicy(policyName, { pluginName, apiName });
|
|
2714
|
-
if (typeof policy2 === "function") {
|
|
2715
|
-
return policy2;
|
|
2716
|
-
}
|
|
2717
|
-
if (policy2.validator) {
|
|
2718
|
-
policy2.validator(config);
|
|
2719
|
-
}
|
|
2720
|
-
return policy2.handler;
|
|
2721
|
-
};
|
|
2722
2856
|
const createPolicy = (options) => {
|
|
2723
2857
|
const { name = "unnamed", validator, handler } = options;
|
|
2724
2858
|
const wrappedValidator = (config) => {
|
|
@@ -2750,10 +2884,7 @@ const createPolicyContext = (type, ctx) => {
|
|
|
2750
2884
|
const policy = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2751
2885
|
__proto__: null,
|
|
2752
2886
|
createPolicy,
|
|
2753
|
-
createPolicyContext
|
|
2754
|
-
get: getPolicy,
|
|
2755
|
-
globalPolicy,
|
|
2756
|
-
resolve: resolvePolicies
|
|
2887
|
+
createPolicyContext
|
|
2757
2888
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2758
2889
|
const nameToSlug = (name, options = { separator: "-" }) => slugify(name, options);
|
|
2759
2890
|
const nameToCollectionName = (name) => slugify(name, { separator: "_" });
|
|
@@ -2763,9 +2894,9 @@ const toRegressedEnumValue = (value) => slugify(value, {
|
|
|
2763
2894
|
separator: "_"
|
|
2764
2895
|
});
|
|
2765
2896
|
const getCommonPath = (...paths) => {
|
|
2766
|
-
const [segments, ...otherSegments] = paths.map((it) =>
|
|
2767
|
-
return
|
|
2768
|
-
|
|
2897
|
+
const [segments, ...otherSegments] = paths.map((it) => ___default.split(it, "/"));
|
|
2898
|
+
return ___default.join(
|
|
2899
|
+
___default.takeWhile(segments, (str, index2) => otherSegments.every((it) => it[index2] === str)),
|
|
2769
2900
|
"/"
|
|
2770
2901
|
);
|
|
2771
2902
|
};
|
|
@@ -2807,9 +2938,9 @@ const arrays = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
2807
2938
|
__proto__: null,
|
|
2808
2939
|
includesString
|
|
2809
2940
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2810
|
-
const keysDeep = (obj, path = []) => !
|
|
2941
|
+
const keysDeep = (obj, path = []) => !___default.isObject(obj) ? [path.join(".")] : ___default.reduce(
|
|
2811
2942
|
obj,
|
|
2812
|
-
(acc, next, key) =>
|
|
2943
|
+
(acc, next, key) => ___default.concat(acc, keysDeep(next, [...path, key])),
|
|
2813
2944
|
[]
|
|
2814
2945
|
);
|
|
2815
2946
|
const objects = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -2873,8 +3004,8 @@ function printValue(value, quoteStrings) {
|
|
|
2873
3004
|
);
|
|
2874
3005
|
}
|
|
2875
3006
|
const strapiID = () => new StrapiIDSchema();
|
|
2876
|
-
const isNotNilTest = (value) => !
|
|
2877
|
-
const isNotNullTest = (value) => !
|
|
3007
|
+
const isNotNilTest = (value) => !___default.isNil(value);
|
|
3008
|
+
const isNotNullTest = (value) => !___default.isNull(value);
|
|
2878
3009
|
yup$1.addMethod(yup$1.mixed, "notNil", function isNotNill(msg = "${path} must be defined.") {
|
|
2879
3010
|
return this.test("defined", msg, isNotNilTest);
|
|
2880
3011
|
});
|
|
@@ -2885,7 +3016,7 @@ yup$1.addMethod(yup$1.mixed, "isFunction", function isFunction(message = "${path
|
|
|
2885
3016
|
return this.test(
|
|
2886
3017
|
"is a function",
|
|
2887
3018
|
message,
|
|
2888
|
-
(value) =>
|
|
3019
|
+
(value) => ___default.isUndefined(value) || ___default.isFunction(value)
|
|
2889
3020
|
);
|
|
2890
3021
|
});
|
|
2891
3022
|
yup$1.addMethod(
|
|
@@ -2917,7 +3048,7 @@ yup$1.addMethod(
|
|
|
2917
3048
|
return this.test(
|
|
2918
3049
|
"only contains functions",
|
|
2919
3050
|
message,
|
|
2920
|
-
(value) =>
|
|
3051
|
+
(value) => ___default.isUndefined(value) || value && Object.values(value).every(___default.isFunction)
|
|
2921
3052
|
);
|
|
2922
3053
|
}
|
|
2923
3054
|
);
|
|
@@ -2992,11 +3123,31 @@ const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
|
|
|
2992
3123
|
isManyToAny,
|
|
2993
3124
|
isOneToAny
|
|
2994
3125
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3126
|
+
const validateZod = (schema) => (data) => {
|
|
3127
|
+
try {
|
|
3128
|
+
return schema.parse(data);
|
|
3129
|
+
} catch (error) {
|
|
3130
|
+
if (error instanceof z.ZodError) {
|
|
3131
|
+
const { message, errors: errors2 } = formatZodErrors(error);
|
|
3132
|
+
throw new ValidationError(message, { errors: errors2 });
|
|
3133
|
+
}
|
|
3134
|
+
throw error;
|
|
3135
|
+
}
|
|
3136
|
+
};
|
|
3137
|
+
const formatZodErrors = (zodError) => ({
|
|
3138
|
+
errors: zodError.errors.map((error) => {
|
|
3139
|
+
return {
|
|
3140
|
+
path: error.path,
|
|
3141
|
+
message: error.message,
|
|
3142
|
+
name: "ValidationError"
|
|
3143
|
+
};
|
|
3144
|
+
}),
|
|
3145
|
+
message: "Validation error"
|
|
3146
|
+
});
|
|
2995
3147
|
export {
|
|
2996
3148
|
arrays,
|
|
2997
3149
|
async,
|
|
2998
3150
|
contentTypes,
|
|
2999
|
-
convertQueryParams,
|
|
3000
3151
|
dates,
|
|
3001
3152
|
env,
|
|
3002
3153
|
errors,
|
|
@@ -3012,16 +3163,18 @@ export {
|
|
|
3012
3163
|
parseType,
|
|
3013
3164
|
policy,
|
|
3014
3165
|
providerFactory,
|
|
3166
|
+
convertQueryParams as queryParams,
|
|
3015
3167
|
relations,
|
|
3016
|
-
index$
|
|
3168
|
+
index$2 as sanitize,
|
|
3017
3169
|
setCreatorFields,
|
|
3018
3170
|
strings,
|
|
3019
3171
|
template,
|
|
3020
|
-
index$
|
|
3172
|
+
index$3 as traverse,
|
|
3021
3173
|
traverseEntity$1 as traverseEntity,
|
|
3022
3174
|
index as validate,
|
|
3023
3175
|
validateYupSchema,
|
|
3024
3176
|
validateYupSchemaSync,
|
|
3177
|
+
validateZod,
|
|
3025
3178
|
yup
|
|
3026
3179
|
};
|
|
3027
3180
|
//# sourceMappingURL=index.mjs.map
|