@fourlights/strapi-plugin-deep-populate 1.1.2 → 1.2.2
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/README.md +58 -43
- package/dist/server/index.js +312 -124
- package/dist/server/index.mjs +311 -123
- package/dist/server/src/config/index.d.ts +10 -0
- package/dist/server/src/content-types/cache/index.d.ts +47 -0
- package/dist/server/src/content-types/cache/schema.d.ts +45 -0
- package/dist/server/src/content-types/index.d.ts +49 -0
- package/dist/server/src/index.d.ts +76 -12
- package/dist/server/src/migrations/index.d.ts +4 -0
- package/dist/server/src/register.d.ts +4 -0
- package/dist/server/src/services/cache.d.ts +14 -0
- package/dist/server/src/services/deep-populate/index.d.ts +5 -3
- package/dist/server/src/services/index.d.ts +16 -12
- package/dist/server/src/services/populate.d.ts +7 -16
- package/package.json +5 -5
package/dist/server/index.mjs
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { dset } from "dset/merge";
|
|
2
|
-
import delve from "dlv";
|
|
3
1
|
import { klona } from "klona/json";
|
|
4
2
|
import require$$1 from "crypto";
|
|
5
3
|
import require$$0$1 from "child_process";
|
|
@@ -13,6 +11,208 @@ import require$$0$6 from "stream";
|
|
|
13
11
|
import require$$2$1 from "util";
|
|
14
12
|
import require$$0$8 from "constants";
|
|
15
13
|
import "node:stream";
|
|
14
|
+
import delve from "dlv";
|
|
15
|
+
import { dset } from "dset/merge";
|
|
16
|
+
const config = {
|
|
17
|
+
default: ({ env: env2 }) => ({ cachePopulate: true, augmentPopulateStar: true }),
|
|
18
|
+
validator: (config2) => {
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const schema$1 = {
|
|
22
|
+
kind: "collectionType",
|
|
23
|
+
collectionName: "caches",
|
|
24
|
+
info: {
|
|
25
|
+
singularName: "cache",
|
|
26
|
+
pluralName: "caches",
|
|
27
|
+
displayName: "Cache",
|
|
28
|
+
description: "Holds cached deep populate object"
|
|
29
|
+
},
|
|
30
|
+
options: {},
|
|
31
|
+
pluginOptions: {
|
|
32
|
+
"content-manager": {
|
|
33
|
+
visible: false
|
|
34
|
+
},
|
|
35
|
+
"content-type-builder": {
|
|
36
|
+
visible: false
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
attributes: {
|
|
40
|
+
hash: {
|
|
41
|
+
type: "string",
|
|
42
|
+
configurable: false,
|
|
43
|
+
required: true
|
|
44
|
+
},
|
|
45
|
+
params: {
|
|
46
|
+
type: "json",
|
|
47
|
+
configurable: false,
|
|
48
|
+
required: true
|
|
49
|
+
},
|
|
50
|
+
populate: {
|
|
51
|
+
type: "json",
|
|
52
|
+
configurable: false
|
|
53
|
+
},
|
|
54
|
+
dependencies: { type: "string", configurable: false }
|
|
55
|
+
},
|
|
56
|
+
// experimental feature:
|
|
57
|
+
indexes: [
|
|
58
|
+
{
|
|
59
|
+
name: "caches_hash_idx",
|
|
60
|
+
columns: ["hash"],
|
|
61
|
+
type: "unique"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
const cache$1 = { schema: schema$1 };
|
|
66
|
+
const contentTypes$1 = { cache: cache$1 };
|
|
67
|
+
async function hasDeepPopulateCacheFullTextIndex(db, tableName, columnName) {
|
|
68
|
+
const knex = db.connection;
|
|
69
|
+
const client = db.dialect.client;
|
|
70
|
+
if (client === "sqlite") {
|
|
71
|
+
return (await db.dialect.schemaInspector.getTables()).includes(`${tableName}_fts`);
|
|
72
|
+
}
|
|
73
|
+
if (client === "mysql" || client === "mysql2") {
|
|
74
|
+
return (await db.dialect.schemaInspector.getIndexes(tableName)).find(
|
|
75
|
+
({ name }) => name === `${tableName}_${columnName}_fulltext`
|
|
76
|
+
) !== void 0;
|
|
77
|
+
}
|
|
78
|
+
if (client === "pg" || client === "postgres") {
|
|
79
|
+
const result = await knex.raw(
|
|
80
|
+
`SELECT * FROM pg_indexes WHERE tablename = '${tableName}' AND indexname = '${tableName}_${columnName}_gin'`
|
|
81
|
+
);
|
|
82
|
+
return result.rows.length > 0;
|
|
83
|
+
}
|
|
84
|
+
console.log(`Full-text index not supported for this database engine (${client})`);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
async function addDeepPopulateCacheFullTextIndex(db, tableName, columnName) {
|
|
88
|
+
const knex = db.connection;
|
|
89
|
+
const hasTable = await knex.schema.hasTable(tableName);
|
|
90
|
+
if (!hasTable) return;
|
|
91
|
+
const hasColumn = await knex.schema.hasColumn(tableName, columnName);
|
|
92
|
+
if (!hasColumn) return;
|
|
93
|
+
const client = db.dialect.client;
|
|
94
|
+
if (client === "sqlite") {
|
|
95
|
+
await knex.raw(`CREATE VIRTUAL TABLE ${tableName}_fts USING fts3(${columnName})`);
|
|
96
|
+
await knex.raw(`INSERT INTO ${tableName}_fts (${columnName}) SELECT ${columnName} FROM ${tableName}`);
|
|
97
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
98
|
+
await knex.raw(`ALTER TABLE ${tableName} ADD FULLTEXT INDEX ${tableName}_${columnName}_fulltext (${columnName})`);
|
|
99
|
+
} else if (client === "pg" || client === "postgres") {
|
|
100
|
+
await knex.raw(
|
|
101
|
+
`CREATE INDEX ${tableName}_${columnName}_gin ON ${tableName} USING GIN (to_tsvector('english', ${columnName}))`
|
|
102
|
+
);
|
|
103
|
+
} else {
|
|
104
|
+
console.log(`Full-text index not supported for this database engine (${client})`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function removeDeepPopulateCacheFullTextIndex(db, tableName, columnName) {
|
|
108
|
+
const knex = db.connection;
|
|
109
|
+
const hasTable = await knex.schema.hasTable(tableName);
|
|
110
|
+
if (!hasTable) return;
|
|
111
|
+
const hasColumn = await knex.schema.hasColumn(tableName, columnName);
|
|
112
|
+
if (!hasColumn) return;
|
|
113
|
+
const client = db.dialect.client;
|
|
114
|
+
if (client === "sqlite") {
|
|
115
|
+
await knex.raw(`DROP TABLE ${tableName}_fts`);
|
|
116
|
+
} else if (client === "mysql" || client === "mysql2") {
|
|
117
|
+
await knex.raw(`ALTER TABLE ${tableName} DROP INDEX ${tableName}_${columnName}_fulltext`);
|
|
118
|
+
} else if (client === "pg" || client === "postgres") {
|
|
119
|
+
await knex.raw(`DROP INDEX ${tableName}_${columnName}_gin`);
|
|
120
|
+
} else {
|
|
121
|
+
console.log(`Full-text index not supported for this database engine (${client})`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const register = async ({ strapi: strapi2 }) => {
|
|
125
|
+
strapi2.hook("strapi::content-types.afterSync").register(async () => {
|
|
126
|
+
const tableName = "caches";
|
|
127
|
+
const columnName = "dependencies";
|
|
128
|
+
const hasIndex = await hasDeepPopulateCacheFullTextIndex(strapi2.db, tableName, columnName);
|
|
129
|
+
if (strapi2.config.get("plugin::deep-populate").cachePopulate === true) {
|
|
130
|
+
if (!hasIndex) {
|
|
131
|
+
await addDeepPopulateCacheFullTextIndex(strapi2.db, tableName, columnName);
|
|
132
|
+
}
|
|
133
|
+
} else if (hasIndex) {
|
|
134
|
+
await removeDeepPopulateCacheFullTextIndex(strapi2.db, tableName, columnName);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
strapi2.documents.use(async (context, next) => {
|
|
138
|
+
const { cachePopulate, augmentPopulateStar } = strapi2.config.get("plugin::deep-populate");
|
|
139
|
+
if (
|
|
140
|
+
// do nothing if not configured
|
|
141
|
+
!cachePopulate && !augmentPopulateStar || context.uid === "plugin::deep-populate.cache"
|
|
142
|
+
)
|
|
143
|
+
return await next();
|
|
144
|
+
const populateService = strapi2.plugin("deep-populate").service("populate");
|
|
145
|
+
const cacheService = strapi2.plugin("deep-populate").service("cache");
|
|
146
|
+
const { populate: populate2 } = context.params;
|
|
147
|
+
const returnDeeplyPopulated = augmentPopulateStar && populate2 === "*";
|
|
148
|
+
if (cachePopulate && context.action === "delete")
|
|
149
|
+
await cacheService.clear({ ...context.params, contentType: context.uid });
|
|
150
|
+
const originalFields = klona(context.fields);
|
|
151
|
+
if (returnDeeplyPopulated && ["findOne", "findFirst", "findMany"].includes(context.action))
|
|
152
|
+
context.fields = ["documentId", "status", "locale"];
|
|
153
|
+
const result = await next();
|
|
154
|
+
if (["create", "update"].includes(context.action)) {
|
|
155
|
+
const { documentId, status: status2, locale: locale2 } = result;
|
|
156
|
+
if (cachePopulate && context.action === "update")
|
|
157
|
+
await cacheService.clear({ ...context.params, contentType: context.uid });
|
|
158
|
+
if (cachePopulate || returnDeeplyPopulated) {
|
|
159
|
+
const deepPopulate = await populateService.get({ contentType: context.uid, documentId, status: status2, locale: locale2 });
|
|
160
|
+
if (returnDeeplyPopulated)
|
|
161
|
+
return await strapi2.documents(context.uid).findOne({ documentId, status: status2, locale: locale2, fields: originalFields, populate: deepPopulate });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (returnDeeplyPopulated && ["findOne", "findFirst"].includes(context.action)) {
|
|
165
|
+
const { documentId, status: status2, locale: locale2 } = result;
|
|
166
|
+
const deepPopulate = await populateService.get({ contentType: context.uid, documentId, status: status2, locale: locale2 });
|
|
167
|
+
return await strapi2.documents(context.uid).findOne({ documentId, status: status2, locale: locale2, fields: originalFields, populate: deepPopulate });
|
|
168
|
+
}
|
|
169
|
+
if (returnDeeplyPopulated && context.action === "findMany") {
|
|
170
|
+
return await Promise.all(
|
|
171
|
+
result.map(async ({ documentId, status: status2, locale: locale2 }) => {
|
|
172
|
+
const deepPopulate = await populateService.get({ contentType: context.uid, documentId, status: status2, locale: locale2 });
|
|
173
|
+
return await strapi2.documents(context.uid).findOne({ documentId, status: status2, locale: locale2, fields: originalFields, populate: deepPopulate });
|
|
174
|
+
})
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
const getHash = (params) => {
|
|
181
|
+
return `${params.contentType}-${params.documentId}-${params.locale}-${params.status}-${params.omitEmpty ? "sparse" : "full"}`;
|
|
182
|
+
};
|
|
183
|
+
const cache = ({ strapi: strapi2 }) => ({
|
|
184
|
+
async get(params) {
|
|
185
|
+
const entry = await strapi2.documents("plugin::deep-populate.cache").findFirst({ filters: { hash: { $eq: getHash(params) } } });
|
|
186
|
+
return entry ? entry.populate : null;
|
|
187
|
+
},
|
|
188
|
+
async set({ populate: populate2, dependencies, ...params }) {
|
|
189
|
+
return await strapi2.documents("plugin::deep-populate.cache").create({ data: { hash: getHash(params), params, populate: populate2, dependencies: dependencies.join(",") } });
|
|
190
|
+
},
|
|
191
|
+
async clear(params) {
|
|
192
|
+
const entry = await strapi2.documents("plugin::deep-populate.cache").findFirst({ filters: { hash: { $eq: getHash(params) } } });
|
|
193
|
+
let retval = null;
|
|
194
|
+
if (entry) {
|
|
195
|
+
retval = await strapi2.documents("plugin::deep-populate.cache").delete({ documentId: entry.documentId });
|
|
196
|
+
}
|
|
197
|
+
await this.refreshDependents(params.documentId);
|
|
198
|
+
return retval;
|
|
199
|
+
},
|
|
200
|
+
async refreshDependents(documentId) {
|
|
201
|
+
const entries = await strapi2.documents("plugin::deep-populate.cache").findMany({ filters: { dependencies: { $contains: documentId } }, fields: ["documentId", "params"] });
|
|
202
|
+
const deleted = await strapi2.db.query("plugin::deep-populate.cache").deleteMany({
|
|
203
|
+
where: {
|
|
204
|
+
documentId: { $in: entries.map((x) => x.documentId) }
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
if (deleted.count !== entries.length)
|
|
208
|
+
console.error(`Deleted count ${deleted.count} does not match entries count ${entries.length}`);
|
|
209
|
+
const batchSize = 5;
|
|
210
|
+
for (let i = 0; i < entries.length; i += batchSize) {
|
|
211
|
+
const batch = entries.slice(i, i + batchSize);
|
|
212
|
+
await Promise.all(batch.map((entry) => strapi2.service("plugin::deep-populate.populate").get(entry.params)));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
});
|
|
16
216
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
17
217
|
function getDefaultExportFromCjs(x) {
|
|
18
218
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
@@ -588,8 +788,8 @@ lodash.exports;
|
|
|
588
788
|
return object2[key];
|
|
589
789
|
});
|
|
590
790
|
}
|
|
591
|
-
function cacheHas2(
|
|
592
|
-
return
|
|
791
|
+
function cacheHas2(cache2, key) {
|
|
792
|
+
return cache2.has(key);
|
|
593
793
|
}
|
|
594
794
|
function charsStartIndex(strSymbols, chrSymbols) {
|
|
595
795
|
var index2 = -1, length = strSymbols.length;
|
|
@@ -1404,8 +1604,8 @@ lodash.exports;
|
|
|
1404
1604
|
if (!(seen ? cacheHas2(seen, computed) : includes2(result2, computed, comparator))) {
|
|
1405
1605
|
othIndex = othLength;
|
|
1406
1606
|
while (--othIndex) {
|
|
1407
|
-
var
|
|
1408
|
-
if (!(
|
|
1607
|
+
var cache2 = caches[othIndex];
|
|
1608
|
+
if (!(cache2 ? cacheHas2(cache2, computed) : includes2(arrays[othIndex], computed, comparator))) {
|
|
1409
1609
|
continue outer;
|
|
1410
1610
|
}
|
|
1411
1611
|
}
|
|
@@ -2979,12 +3179,12 @@ lodash.exports;
|
|
|
2979
3179
|
}
|
|
2980
3180
|
function memoizeCapped2(func) {
|
|
2981
3181
|
var result2 = memoize2(func, function(key) {
|
|
2982
|
-
if (
|
|
2983
|
-
|
|
3182
|
+
if (cache2.size === MAX_MEMOIZE_SIZE2) {
|
|
3183
|
+
cache2.clear();
|
|
2984
3184
|
}
|
|
2985
3185
|
return key;
|
|
2986
3186
|
});
|
|
2987
|
-
var
|
|
3187
|
+
var cache2 = result2.cache;
|
|
2988
3188
|
return result2;
|
|
2989
3189
|
}
|
|
2990
3190
|
function mergeData(data, source) {
|
|
@@ -3938,12 +4138,12 @@ lodash.exports;
|
|
|
3938
4138
|
throw new TypeError2(FUNC_ERROR_TEXT2);
|
|
3939
4139
|
}
|
|
3940
4140
|
var memoized = function() {
|
|
3941
|
-
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0],
|
|
3942
|
-
if (
|
|
3943
|
-
return
|
|
4141
|
+
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache2 = memoized.cache;
|
|
4142
|
+
if (cache2.has(key)) {
|
|
4143
|
+
return cache2.get(key);
|
|
3944
4144
|
}
|
|
3945
4145
|
var result2 = func.apply(this, args);
|
|
3946
|
-
memoized.cache =
|
|
4146
|
+
memoized.cache = cache2.set(key, result2) || cache2;
|
|
3947
4147
|
return result2;
|
|
3948
4148
|
};
|
|
3949
4149
|
memoized.cache = new (memoize2.Cache || MapCache2)();
|
|
@@ -9205,7 +9405,7 @@ function baseConvert(util2, name, func, options) {
|
|
|
9205
9405
|
throw new TypeError();
|
|
9206
9406
|
}
|
|
9207
9407
|
options || (options = {});
|
|
9208
|
-
var
|
|
9408
|
+
var config2 = {
|
|
9209
9409
|
"cap": "cap" in options ? options.cap : true,
|
|
9210
9410
|
"curry": "curry" in options ? options.curry : true,
|
|
9211
9411
|
"fixed": "fixed" in options ? options.fixed : true,
|
|
@@ -9241,7 +9441,7 @@ function baseConvert(util2, name, func, options) {
|
|
|
9241
9441
|
"iteratee": function(iteratee) {
|
|
9242
9442
|
return function() {
|
|
9243
9443
|
var func2 = arguments[0], arity = arguments[1], result = iteratee(func2, arity), length = result.length;
|
|
9244
|
-
if (
|
|
9444
|
+
if (config2.cap && typeof arity == "number") {
|
|
9245
9445
|
arity = arity > 2 ? arity - 2 : 1;
|
|
9246
9446
|
return length && length <= arity ? result : baseAry(result, arity);
|
|
9247
9447
|
}
|
|
@@ -9291,7 +9491,7 @@ function baseConvert(util2, name, func, options) {
|
|
|
9291
9491
|
}
|
|
9292
9492
|
};
|
|
9293
9493
|
function castCap(name2, func2) {
|
|
9294
|
-
if (
|
|
9494
|
+
if (config2.cap) {
|
|
9295
9495
|
var indexes = mapping.iterateeRearg[name2];
|
|
9296
9496
|
if (indexes) {
|
|
9297
9497
|
return iterateeRearg(func2, indexes);
|
|
@@ -9304,17 +9504,17 @@ function baseConvert(util2, name, func, options) {
|
|
|
9304
9504
|
return func2;
|
|
9305
9505
|
}
|
|
9306
9506
|
function castCurry(name2, func2, n) {
|
|
9307
|
-
return forceCurry ||
|
|
9507
|
+
return forceCurry || config2.curry && n > 1 ? curry(func2, n) : func2;
|
|
9308
9508
|
}
|
|
9309
9509
|
function castFixed(name2, func2, n) {
|
|
9310
|
-
if (
|
|
9510
|
+
if (config2.fixed && (forceFixed || !mapping.skipFixed[name2])) {
|
|
9311
9511
|
var data = mapping.methodSpread[name2], start = data && data.start;
|
|
9312
9512
|
return start === void 0 ? ary(func2, n) : flatSpread(func2, start);
|
|
9313
9513
|
}
|
|
9314
9514
|
return func2;
|
|
9315
9515
|
}
|
|
9316
9516
|
function castRearg(name2, func2, n) {
|
|
9317
|
-
return
|
|
9517
|
+
return config2.rearg && n > 1 && (forceRearg || !mapping.skipRearg[name2]) ? rearg(func2, mapping.methodRearg[name2] || mapping.aryRearg[n]) : func2;
|
|
9318
9518
|
}
|
|
9319
9519
|
function cloneByPath(object2, path2) {
|
|
9320
9520
|
path2 = toPath(path2);
|
|
@@ -9359,7 +9559,7 @@ function baseConvert(util2, name, func, options) {
|
|
|
9359
9559
|
while (length--) {
|
|
9360
9560
|
args[length] = arguments[length];
|
|
9361
9561
|
}
|
|
9362
|
-
var index2 =
|
|
9562
|
+
var index2 = config2.rearg ? 0 : length - 1;
|
|
9363
9563
|
args[index2] = transform2(args[index2]);
|
|
9364
9564
|
return func2.apply(void 0, args);
|
|
9365
9565
|
};
|
|
@@ -9368,7 +9568,7 @@ function baseConvert(util2, name, func, options) {
|
|
|
9368
9568
|
var result, realName = mapping.aliasToReal[name2] || name2, wrapped = func2, wrapper = wrappers[realName];
|
|
9369
9569
|
if (wrapper) {
|
|
9370
9570
|
wrapped = wrapper(func2);
|
|
9371
|
-
} else if (
|
|
9571
|
+
} else if (config2.immutable) {
|
|
9372
9572
|
if (mapping.mutate.array[realName]) {
|
|
9373
9573
|
wrapped = wrapImmutable(func2, cloneArray);
|
|
9374
9574
|
} else if (mapping.mutate.object[realName]) {
|
|
@@ -10660,12 +10860,12 @@ function memoize$1(func, resolver) {
|
|
|
10660
10860
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
10661
10861
|
}
|
|
10662
10862
|
var memoized = function() {
|
|
10663
|
-
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0],
|
|
10664
|
-
if (
|
|
10665
|
-
return
|
|
10863
|
+
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache2 = memoized.cache;
|
|
10864
|
+
if (cache2.has(key)) {
|
|
10865
|
+
return cache2.get(key);
|
|
10666
10866
|
}
|
|
10667
10867
|
var result = func.apply(this, args);
|
|
10668
|
-
memoized.cache =
|
|
10868
|
+
memoized.cache = cache2.set(key, result) || cache2;
|
|
10669
10869
|
return result;
|
|
10670
10870
|
};
|
|
10671
10871
|
memoized.cache = new (memoize$1.Cache || MapCache$2)();
|
|
@@ -10677,12 +10877,12 @@ var memoize = memoize_1;
|
|
|
10677
10877
|
var MAX_MEMOIZE_SIZE = 500;
|
|
10678
10878
|
function memoizeCapped$1(func) {
|
|
10679
10879
|
var result = memoize(func, function(key) {
|
|
10680
|
-
if (
|
|
10681
|
-
|
|
10880
|
+
if (cache2.size === MAX_MEMOIZE_SIZE) {
|
|
10881
|
+
cache2.clear();
|
|
10682
10882
|
}
|
|
10683
10883
|
return key;
|
|
10684
10884
|
});
|
|
10685
|
-
var
|
|
10885
|
+
var cache2 = result.cache;
|
|
10686
10886
|
return result;
|
|
10687
10887
|
}
|
|
10688
10888
|
var _memoizeCapped = memoizeCapped$1;
|
|
@@ -11184,8 +11384,8 @@ function arraySome$1(array2, predicate) {
|
|
|
11184
11384
|
return false;
|
|
11185
11385
|
}
|
|
11186
11386
|
var _arraySome = arraySome$1;
|
|
11187
|
-
function cacheHas$1(
|
|
11188
|
-
return
|
|
11387
|
+
function cacheHas$1(cache2, key) {
|
|
11388
|
+
return cache2.has(key);
|
|
11189
11389
|
}
|
|
11190
11390
|
var _cacheHas = cacheHas$1;
|
|
11191
11391
|
var SetCache = _SetCache, arraySome = _arraySome, cacheHas = _cacheHas;
|
|
@@ -11810,7 +12010,7 @@ function _objectWithoutPropertiesLoose(source, excluded) {
|
|
|
11810
12010
|
}
|
|
11811
12011
|
return target;
|
|
11812
12012
|
}
|
|
11813
|
-
function createValidation(
|
|
12013
|
+
function createValidation(config2) {
|
|
11814
12014
|
function validate(_ref, cb) {
|
|
11815
12015
|
let {
|
|
11816
12016
|
value,
|
|
@@ -11825,7 +12025,7 @@ function createValidation(config) {
|
|
|
11825
12025
|
test,
|
|
11826
12026
|
params,
|
|
11827
12027
|
message
|
|
11828
|
-
} =
|
|
12028
|
+
} = config2;
|
|
11829
12029
|
let {
|
|
11830
12030
|
parent,
|
|
11831
12031
|
context
|
|
@@ -11880,7 +12080,7 @@ function createValidation(config) {
|
|
|
11880
12080
|
else if (!result) cb(createError());
|
|
11881
12081
|
else cb(null, result);
|
|
11882
12082
|
}
|
|
11883
|
-
validate.OPTIONS =
|
|
12083
|
+
validate.OPTIONS = config2;
|
|
11884
12084
|
return validate;
|
|
11885
12085
|
}
|
|
11886
12086
|
let trim = (part) => part.substr(0, part.length - 1).substr(1);
|
|
@@ -24570,7 +24770,7 @@ const isPopulateString = (value) => {
|
|
|
24570
24770
|
};
|
|
24571
24771
|
const isStringArray$1 = (value) => fp.isArray(value) && value.every(fp.isString);
|
|
24572
24772
|
const isObj = (value) => fp.isObject(value);
|
|
24573
|
-
const populate$
|
|
24773
|
+
const populate$2 = traverseFactory().intercept(isPopulateString, async (visitor2, options, populate2, { recurse }) => {
|
|
24574
24774
|
const populateObject = pathsToObjectPopulate([populate2]);
|
|
24575
24775
|
const traversedPopulate = await recurse(visitor2, options, populateObject);
|
|
24576
24776
|
const [result] = objectPopulateToPaths(traversedPopulate);
|
|
@@ -24738,7 +24938,7 @@ const populate$1 = traverseFactory().intercept(isPopulateString, async (visitor2
|
|
|
24738
24938
|
}
|
|
24739
24939
|
}
|
|
24740
24940
|
);
|
|
24741
|
-
const traverseQueryPopulate = fp.curry(populate$
|
|
24941
|
+
const traverseQueryPopulate = fp.curry(populate$2.traverse);
|
|
24742
24942
|
const objectPopulateToPaths = (input) => {
|
|
24743
24943
|
const paths = [];
|
|
24744
24944
|
function traverse(currentObj, parentPath) {
|
|
@@ -25058,54 +25258,40 @@ const hasValue = (value) => {
|
|
|
25058
25258
|
return !(value === null || value === void 0 || Array.isArray(value) && value.length === 0 || typeof value === "object" && isEmpty(value));
|
|
25059
25259
|
};
|
|
25060
25260
|
async function _populateComponent({
|
|
25061
|
-
mainUid,
|
|
25062
|
-
mainDocumentId,
|
|
25063
|
-
schema: schema2,
|
|
25064
25261
|
populate: populate2 = {},
|
|
25065
25262
|
lookup,
|
|
25263
|
+
attrName,
|
|
25066
25264
|
inDynamicZone = false,
|
|
25067
|
-
|
|
25068
|
-
omitEmpty
|
|
25265
|
+
...params
|
|
25069
25266
|
}) {
|
|
25070
|
-
const attrName = lookup.pop();
|
|
25071
25267
|
const componentLookup = lookup.length === 0 ? [attrName] : [...lookup, inDynamicZone ? "on" : "populate", attrName];
|
|
25072
|
-
const componentPopulate =
|
|
25268
|
+
const componentPopulate = populate2;
|
|
25073
25269
|
dset(componentPopulate, componentLookup, { populate: "*" });
|
|
25074
25270
|
const nestedPopulate = await _populate({
|
|
25075
|
-
mainUid,
|
|
25076
|
-
mainDocumentId,
|
|
25077
|
-
schema: schema2,
|
|
25078
25271
|
populate: componentPopulate,
|
|
25079
25272
|
lookup: componentLookup,
|
|
25080
|
-
|
|
25081
|
-
omitEmpty
|
|
25273
|
+
...params
|
|
25082
25274
|
});
|
|
25083
25275
|
return isEmpty(nestedPopulate) ? true : { populate: nestedPopulate };
|
|
25084
25276
|
}
|
|
25085
25277
|
async function _populateDynamicZone({
|
|
25086
|
-
mainUid,
|
|
25087
|
-
mainDocumentId,
|
|
25088
25278
|
components,
|
|
25089
|
-
populate: populate2,
|
|
25090
25279
|
lookup,
|
|
25091
|
-
|
|
25092
|
-
|
|
25280
|
+
attrName,
|
|
25281
|
+
...params
|
|
25093
25282
|
}) {
|
|
25094
|
-
const
|
|
25095
|
-
|
|
25096
|
-
|
|
25097
|
-
|
|
25098
|
-
schema:
|
|
25099
|
-
|
|
25100
|
-
|
|
25283
|
+
const dynamicZoneLookup = [...lookup, attrName];
|
|
25284
|
+
const resolvedPopulate = {};
|
|
25285
|
+
for (const component of components) {
|
|
25286
|
+
const componentPopulate = await _populateComponent({
|
|
25287
|
+
schema: component,
|
|
25288
|
+
lookup: dynamicZoneLookup,
|
|
25289
|
+
attrName: component,
|
|
25101
25290
|
inDynamicZone: true,
|
|
25102
|
-
|
|
25103
|
-
omitEmpty
|
|
25291
|
+
...params
|
|
25104
25292
|
});
|
|
25105
|
-
|
|
25106
|
-
|
|
25107
|
-
return newPop;
|
|
25108
|
-
}, Promise.resolve({}));
|
|
25293
|
+
dset(resolvedPopulate, [component], componentPopulate);
|
|
25294
|
+
}
|
|
25109
25295
|
if (isEmpty(resolvedPopulate)) return void 0;
|
|
25110
25296
|
return { on: resolvedPopulate };
|
|
25111
25297
|
}
|
|
@@ -25116,18 +25302,23 @@ async function _populateRelation({
|
|
|
25116
25302
|
contentType,
|
|
25117
25303
|
relation,
|
|
25118
25304
|
resolvedRelations,
|
|
25119
|
-
omitEmpty
|
|
25305
|
+
omitEmpty,
|
|
25306
|
+
locale: locale2,
|
|
25307
|
+
status: status2
|
|
25120
25308
|
}) {
|
|
25121
25309
|
const isSingleRelation = !Array.isArray(relation);
|
|
25122
25310
|
const relations = isSingleRelation ? [relation] : relation;
|
|
25123
|
-
|
|
25311
|
+
const nonResolvedRelations = relations.filter(({ documentId }) => !resolvedRelations.has(documentId));
|
|
25312
|
+
for (const relation2 of nonResolvedRelations) {
|
|
25124
25313
|
resolvedRelations.set(relation2.documentId, {});
|
|
25125
25314
|
const relationPopulate = await _populate({
|
|
25126
|
-
|
|
25127
|
-
|
|
25315
|
+
contentType,
|
|
25316
|
+
documentId: relation2.documentId,
|
|
25128
25317
|
schema: contentType,
|
|
25129
25318
|
resolvedRelations,
|
|
25130
|
-
omitEmpty
|
|
25319
|
+
omitEmpty,
|
|
25320
|
+
locale: locale2,
|
|
25321
|
+
status: status2
|
|
25131
25322
|
});
|
|
25132
25323
|
resolvedRelations.set(relation2.documentId, relationPopulate);
|
|
25133
25324
|
}
|
|
@@ -25157,7 +25348,7 @@ const _resolveValue = ({ document: document2, lookup, attrName }) => {
|
|
|
25157
25348
|
const childLookup = lookup[populateIdx + 1];
|
|
25158
25349
|
const parentValue2 = delve(document2, parentLookup);
|
|
25159
25350
|
const childValue = (Array.isArray(parentValue2) ? parentValue2 : [parentValue2]).map(
|
|
25160
|
-
(v) => _resolveValue({ document:
|
|
25351
|
+
(v) => _resolveValue({ document: v, lookup: childLookup, attrName })
|
|
25161
25352
|
);
|
|
25162
25353
|
return childValue.find((v) => hasValue(v));
|
|
25163
25354
|
}
|
|
@@ -25168,18 +25359,18 @@ const _resolveValue = ({ document: document2, lookup, attrName }) => {
|
|
|
25168
25359
|
return parentValue?.[attrName];
|
|
25169
25360
|
};
|
|
25170
25361
|
async function _populate({
|
|
25171
|
-
|
|
25172
|
-
mainDocumentId,
|
|
25362
|
+
contentType,
|
|
25173
25363
|
schema: schema2,
|
|
25174
25364
|
populate: populate2 = {},
|
|
25175
25365
|
lookup = [],
|
|
25176
|
-
resolvedRelations
|
|
25177
|
-
omitEmpty
|
|
25366
|
+
resolvedRelations,
|
|
25367
|
+
omitEmpty,
|
|
25368
|
+
...params
|
|
25178
25369
|
}) {
|
|
25179
25370
|
const newPopulate = {};
|
|
25180
|
-
|
|
25181
|
-
|
|
25182
|
-
|
|
25371
|
+
let relations = getRelations(strapi.getModel(schema2));
|
|
25372
|
+
let currentPopulate = klona(populate2);
|
|
25373
|
+
resolvedRelations.set(params.documentId, true);
|
|
25183
25374
|
for (const [attrName] of relations) {
|
|
25184
25375
|
if (lookup.length > 0) {
|
|
25185
25376
|
const parent = delve(currentPopulate, lookup);
|
|
@@ -25190,47 +25381,56 @@ async function _populate({
|
|
|
25190
25381
|
dset(currentPopulate, attrName, { populate: "*" });
|
|
25191
25382
|
}
|
|
25192
25383
|
}
|
|
25193
|
-
|
|
25194
|
-
|
|
25384
|
+
let document2 = await strapi.documents(contentType).findOne({
|
|
25385
|
+
...params,
|
|
25195
25386
|
populate: currentPopulate ? currentPopulate : "*"
|
|
25196
25387
|
});
|
|
25388
|
+
currentPopulate = null;
|
|
25389
|
+
const resolveRelations = [];
|
|
25197
25390
|
for (const [attrName, attr] of relations) {
|
|
25198
25391
|
const value = _resolveValue({ document: document2, attrName, lookup });
|
|
25199
25392
|
if (!hasValue(value)) {
|
|
25200
25393
|
if (!omitEmpty) newPopulate[attrName] = true;
|
|
25201
25394
|
continue;
|
|
25202
25395
|
}
|
|
25396
|
+
resolveRelations.push([attrName, attr, value]);
|
|
25397
|
+
}
|
|
25398
|
+
relations = null;
|
|
25399
|
+
document2 = null;
|
|
25400
|
+
for (const [attrName, attr, value] of resolveRelations) {
|
|
25203
25401
|
if (contentTypes.isDynamicZoneAttribute(attr)) {
|
|
25204
25402
|
const relComponents = value.map(
|
|
25205
25403
|
(dataComponent) => attr.components.find((schemaComponent) => schemaComponent === dataComponent.__component)
|
|
25206
25404
|
);
|
|
25207
25405
|
newPopulate[attrName] = await _populateDynamicZone({
|
|
25208
|
-
|
|
25209
|
-
mainDocumentId,
|
|
25406
|
+
contentType,
|
|
25210
25407
|
components: relComponents,
|
|
25211
|
-
lookup
|
|
25408
|
+
lookup,
|
|
25409
|
+
attrName,
|
|
25212
25410
|
resolvedRelations,
|
|
25213
|
-
omitEmpty
|
|
25411
|
+
omitEmpty,
|
|
25412
|
+
...params
|
|
25214
25413
|
});
|
|
25215
25414
|
}
|
|
25216
25415
|
if (contentTypes.isRelationalAttribute(attr)) {
|
|
25217
|
-
const { target: relContentType } = attr;
|
|
25218
|
-
resolvedRelations.set(mainDocumentId, true);
|
|
25219
25416
|
newPopulate[attrName] = await _populateRelation({
|
|
25220
|
-
contentType:
|
|
25417
|
+
contentType: attr.target,
|
|
25221
25418
|
relation: value,
|
|
25222
25419
|
resolvedRelations,
|
|
25223
|
-
omitEmpty
|
|
25420
|
+
omitEmpty,
|
|
25421
|
+
locale: params.locale,
|
|
25422
|
+
status: params.status
|
|
25224
25423
|
});
|
|
25225
25424
|
}
|
|
25226
25425
|
if (contentTypes.isComponentAttribute(attr) && !contentTypes.isDynamicZoneAttribute(attr)) {
|
|
25227
25426
|
newPopulate[attrName] = await _populateComponent({
|
|
25228
|
-
|
|
25229
|
-
mainDocumentId,
|
|
25427
|
+
contentType,
|
|
25230
25428
|
schema: attr.component,
|
|
25231
|
-
lookup
|
|
25429
|
+
lookup,
|
|
25430
|
+
attrName,
|
|
25232
25431
|
resolvedRelations,
|
|
25233
|
-
omitEmpty
|
|
25432
|
+
omitEmpty,
|
|
25433
|
+
...params
|
|
25234
25434
|
});
|
|
25235
25435
|
}
|
|
25236
25436
|
if (contentTypes.isMediaAttribute(attr)) {
|
|
@@ -25239,43 +25439,31 @@ async function _populate({
|
|
|
25239
25439
|
}
|
|
25240
25440
|
return newPopulate;
|
|
25241
25441
|
}
|
|
25442
|
+
async function populate$1(params) {
|
|
25443
|
+
const resolvedRelations = /* @__PURE__ */ new Map();
|
|
25444
|
+
const populated = await _populate({ ...params, schema: params.contentType, resolvedRelations });
|
|
25445
|
+
return { populate: populated, dependencies: [...resolvedRelations.keys()] };
|
|
25446
|
+
}
|
|
25242
25447
|
const populate = ({ strapi: strapi2 }) => ({
|
|
25243
|
-
async get({
|
|
25244
|
-
|
|
25245
|
-
|
|
25246
|
-
|
|
25247
|
-
|
|
25248
|
-
|
|
25249
|
-
|
|
25250
|
-
|
|
25251
|
-
strapi2.documents(contentType);
|
|
25252
|
-
const { findOne, ...wrapped } = strapi2.documents(contentType);
|
|
25253
|
-
const wrappedFindOne = async (params) => {
|
|
25254
|
-
const { documentId, populate: originalPopulate } = params;
|
|
25255
|
-
const deepPopulate = await _populate({
|
|
25256
|
-
mainUid: contentType,
|
|
25257
|
-
mainDocumentId: documentId,
|
|
25258
|
-
schema: contentType,
|
|
25259
|
-
omitEmpty: originalPopulate !== "*"
|
|
25260
|
-
});
|
|
25261
|
-
if (originalPopulate && originalPopulate !== "*") {
|
|
25262
|
-
strapi2.log.warn(
|
|
25263
|
-
`passed "populate" will be merged with deepPopulate, which could result in unexpected behavior.`
|
|
25264
|
-
);
|
|
25265
|
-
if (typeof originalPopulate === "object")
|
|
25266
|
-
Object.keys(originalPopulate).map((k) => dset(deepPopulate, k, originalPopulate[k]));
|
|
25267
|
-
if (Array.isArray(originalPopulate)) originalPopulate.map((k) => dset(deepPopulate, k, true));
|
|
25268
|
-
}
|
|
25269
|
-
return await findOne({ ...params, populate: deepPopulate });
|
|
25270
|
-
};
|
|
25271
|
-
return { ...wrapped, findOne: wrappedFindOne };
|
|
25448
|
+
async get(params) {
|
|
25449
|
+
const { cachePopulate } = strapi2.config.get("plugin::deep-populate");
|
|
25450
|
+
if (!cachePopulate) return (await populate$1(params)).populate;
|
|
25451
|
+
const cachedEntry = await strapi2.service("plugin::deep-populate.cache").get(params);
|
|
25452
|
+
if (cachedEntry) return cachedEntry;
|
|
25453
|
+
const resolved = await populate$1(params);
|
|
25454
|
+
await strapi2.service("plugin::deep-populate.cache").set({ ...params, ...resolved });
|
|
25455
|
+
return resolved;
|
|
25272
25456
|
}
|
|
25273
25457
|
});
|
|
25274
25458
|
const services = {
|
|
25275
|
-
populate
|
|
25459
|
+
populate,
|
|
25460
|
+
cache
|
|
25276
25461
|
};
|
|
25277
25462
|
const index = {
|
|
25278
|
-
|
|
25463
|
+
config,
|
|
25464
|
+
contentTypes: contentTypes$1,
|
|
25465
|
+
services,
|
|
25466
|
+
register
|
|
25279
25467
|
};
|
|
25280
25468
|
export {
|
|
25281
25469
|
index as default
|