@strapi/content-manager 0.0.0-experimental.a65a85fdea97faae8679d3ffc5f9d79af61abd26 → 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813
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/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs → ComponentConfigurationPage-BPvzFjM7.mjs} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage--2aLCv-G.mjs.map → ComponentConfigurationPage-BPvzFjM7.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js → ComponentConfigurationPage-DjWJdz6Y.js} +3 -3
- package/dist/_chunks/{ComponentConfigurationPage-43KmCNQE.js.map → ComponentConfigurationPage-DjWJdz6Y.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs → EditConfigurationPage-DacbqQ_f.mjs} +3 -3
- package/dist/_chunks/{EditConfigurationPage-CUcGHHvQ.mjs.map → EditConfigurationPage-DacbqQ_f.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js → EditConfigurationPage-Dmv83RlS.js} +3 -3
- package/dist/_chunks/{EditConfigurationPage-BfFzJ4Br.js.map → EditConfigurationPage-Dmv83RlS.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs → EditViewPage-DDS6H9HO.mjs} +3 -3
- package/dist/_chunks/{EditViewPage-Bm8lgcm6.mjs.map → EditViewPage-DDS6H9HO.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-CzOT5Kpj.js → EditViewPage-DvNpQkam.js} +3 -3
- package/dist/_chunks/{EditViewPage-CzOT5Kpj.js.map → EditViewPage-DvNpQkam.js.map} +1 -1
- package/dist/_chunks/{Field-Dlh0uGnL.mjs → Field-6gvGdPBV.mjs} +3 -3
- package/dist/_chunks/{Field-Dlh0uGnL.mjs.map → Field-6gvGdPBV.mjs.map} +1 -1
- package/dist/_chunks/{Field-Caef4JjM.js → Field-DmVKIAOo.js} +3 -3
- package/dist/_chunks/{Field-Caef4JjM.js.map → Field-DmVKIAOo.js.map} +1 -1
- package/dist/_chunks/{Form-BzuAjtRq.js → Form-CPZC9vWa.js} +5 -5
- package/dist/_chunks/{Form-BzuAjtRq.js.map → Form-CPZC9vWa.js.map} +1 -1
- package/dist/_chunks/{Form-EnaQL_6L.mjs → Form-DW6K1IH-.mjs} +7 -7
- package/dist/_chunks/{Form-EnaQL_6L.mjs.map → Form-DW6K1IH-.mjs.map} +1 -1
- package/dist/_chunks/{History-C17LiyRg.js → History-DeAPlvtv.js} +6 -6
- package/dist/_chunks/History-DeAPlvtv.js.map +1 -0
- package/dist/_chunks/{History-D6sbCJvo.mjs → History-Dmr9fmUA.mjs} +8 -8
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Dks5SX6f.js → ListConfigurationPage-DPCwW5Vr.js} +5 -5
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Ce4qs7qE.mjs → ListConfigurationPage-DhwvYcNv.mjs} +7 -7
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BwrZrPsh.js → ListViewPage-5ySZ-VUs.js} +6 -6
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Be7S5aKL.mjs → ListViewPage-BtAwuYLE.mjs} +8 -8
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Cu5r1-JT.js → NoContentTypePage-DOC_yWOf.js} +4 -4
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CIPmYQMm.mjs → NoContentTypePage-DSPxnxxp.mjs} +6 -6
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-C-j6TEUF.js → NoPermissionsPage-Dwu8rRJu.js} +4 -5
- package/dist/_chunks/NoPermissionsPage-Dwu8rRJu.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-DhJ7LYrr.mjs → NoPermissionsPage-UWDC-1Tw.mjs} +5 -6
- package/dist/_chunks/NoPermissionsPage-UWDC-1Tw.mjs.map +1 -0
- package/dist/_chunks/{Relations-Czs-uZ-s.js → Relations-CgWtgnPe.js} +3 -3
- package/dist/_chunks/{Relations-Czs-uZ-s.js.map → Relations-CgWtgnPe.js.map} +1 -1
- package/dist/_chunks/{Relations-CY7AtkDA.mjs → Relations-J8cscLlR.mjs} +3 -3
- package/dist/_chunks/{Relations-CY7AtkDA.mjs.map → Relations-J8cscLlR.mjs.map} +1 -1
- package/dist/_chunks/{index-X_2tafck.js → index-C6AH2hEl.js} +10 -10
- package/dist/_chunks/{index-X_2tafck.js.map → index-C6AH2hEl.js.map} +1 -1
- package/dist/_chunks/{index-DNVx8ssZ.mjs → index-CwRRo1V9.mjs} +10 -10
- package/dist/_chunks/{index-DNVx8ssZ.mjs.map → index-CwRRo1V9.mjs.map} +1 -1
- package/dist/_chunks/{layout-dBc7wN7L.js → layout-B_SXLhqf.js} +5 -5
- package/dist/_chunks/{layout-dBc7wN7L.js.map → layout-B_SXLhqf.js.map} +1 -1
- package/dist/_chunks/{layout-Dnh0PNp9.mjs → layout-jIDzX0Fp.mjs} +6 -6
- package/dist/_chunks/{layout-Dnh0PNp9.mjs.map → layout-jIDzX0Fp.mjs.map} +1 -1
- package/dist/_chunks/{relations-Dx7tMKJN.mjs → relations-CuvIgCqI.mjs} +2 -2
- package/dist/_chunks/{relations-Dx7tMKJN.mjs.map → relations-CuvIgCqI.mjs.map} +1 -1
- package/dist/_chunks/{relations-4pHtBrHJ.js → relations-iBMa_OFG.js} +2 -2
- package/dist/_chunks/{relations-4pHtBrHJ.js.map → relations-iBMa_OFG.js.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +256 -211
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +256 -211
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/history/services/history.d.ts +2 -4
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/index.d.ts +6 -2
- package/dist/server/src/history/services/index.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts +9 -0
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -0
- package/dist/server/src/history/services/utils.d.ts +41 -9
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/history/utils.d.ts +6 -2
- package/dist/server/src/history/utils.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/_chunks/History-C17LiyRg.js.map +0 -1
- package/dist/_chunks/History-D6sbCJvo.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Ce4qs7qE.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Dks5SX6f.js.map +0 -1
- package/dist/_chunks/ListViewPage-Be7S5aKL.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BwrZrPsh.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-CIPmYQMm.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-Cu5r1-JT.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-C-j6TEUF.js.map +0 -1
- package/dist/_chunks/NoPermissionsPage-DhJ7LYrr.mjs.map +0 -1
package/dist/server/index.js
CHANGED
@@ -138,40 +138,65 @@ const FIELDS_TO_IGNORE = [
|
|
138
138
|
"strapi_stage",
|
139
139
|
"strapi_assignee"
|
140
140
|
];
|
141
|
-
const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
|
142
|
-
const sanitizedContentTypeSchemaAttributes = fp.omit(FIELDS_TO_IGNORE, contentTypeSchemaAttributes);
|
143
|
-
const reduceDifferenceToAttributesObject = (diffKeys, source) => {
|
144
|
-
return diffKeys.reduce((previousAttributesObject, diffKey) => {
|
145
|
-
previousAttributesObject[diffKey] = source[diffKey];
|
146
|
-
return previousAttributesObject;
|
147
|
-
}, {});
|
148
|
-
};
|
149
|
-
const versionSchemaKeys = Object.keys(versionSchemaAttributes);
|
150
|
-
const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
|
151
|
-
const uniqueToContentType = fp.difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
|
152
|
-
const added = reduceDifferenceToAttributesObject(
|
153
|
-
uniqueToContentType,
|
154
|
-
sanitizedContentTypeSchemaAttributes
|
155
|
-
);
|
156
|
-
const uniqueToVersion = fp.difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
|
157
|
-
const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
|
158
|
-
return { added, removed };
|
159
|
-
};
|
160
141
|
const DEFAULT_RETENTION_DAYS = 90;
|
161
|
-
const
|
162
|
-
const
|
163
|
-
|
164
|
-
|
142
|
+
const createServiceUtils = ({ strapi: strapi2 }) => {
|
143
|
+
const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
|
144
|
+
const sanitizedContentTypeSchemaAttributes = fp.omit(
|
145
|
+
FIELDS_TO_IGNORE,
|
146
|
+
contentTypeSchemaAttributes
|
147
|
+
);
|
148
|
+
const reduceDifferenceToAttributesObject = (diffKeys, source) => {
|
149
|
+
return diffKeys.reduce(
|
150
|
+
(previousAttributesObject, diffKey) => {
|
151
|
+
previousAttributesObject[diffKey] = source[diffKey];
|
152
|
+
return previousAttributesObject;
|
153
|
+
},
|
154
|
+
{}
|
155
|
+
);
|
156
|
+
};
|
157
|
+
const versionSchemaKeys = Object.keys(versionSchemaAttributes);
|
158
|
+
const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
|
159
|
+
const uniqueToContentType = fp.difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
|
160
|
+
const added = reduceDifferenceToAttributesObject(
|
161
|
+
uniqueToContentType,
|
162
|
+
sanitizedContentTypeSchemaAttributes
|
163
|
+
);
|
164
|
+
const uniqueToVersion = fp.difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
|
165
|
+
const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
|
166
|
+
return { added, removed };
|
165
167
|
};
|
166
|
-
const
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
168
|
+
const getRelationRestoreValue = async (versionRelationData, attribute) => {
|
169
|
+
if (Array.isArray(versionRelationData)) {
|
170
|
+
if (versionRelationData.length === 0)
|
171
|
+
return versionRelationData;
|
172
|
+
const existingAndMissingRelations = await Promise.all(
|
173
|
+
versionRelationData.map((relation) => {
|
174
|
+
return strapi2.documents(attribute.target).findOne({
|
175
|
+
documentId: relation.documentId,
|
176
|
+
locale: relation.locale || void 0
|
177
|
+
});
|
178
|
+
})
|
179
|
+
);
|
180
|
+
return existingAndMissingRelations.filter(
|
181
|
+
(relation) => relation !== null
|
182
|
+
);
|
173
183
|
}
|
174
|
-
return
|
184
|
+
return strapi2.documents(attribute.target).findOne({
|
185
|
+
documentId: versionRelationData.documentId,
|
186
|
+
locale: versionRelationData.locale || void 0
|
187
|
+
});
|
188
|
+
};
|
189
|
+
const getMediaRestoreValue = async (versionRelationData, attribute) => {
|
190
|
+
if (attribute.multiple) {
|
191
|
+
const existingAndMissingMedias = await Promise.all(
|
192
|
+
// @ts-expect-error Fix the type definitions so this isn't any
|
193
|
+
versionRelationData.map((media) => {
|
194
|
+
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
|
195
|
+
})
|
196
|
+
);
|
197
|
+
return existingAndMissingMedias.filter((media) => media != null);
|
198
|
+
}
|
199
|
+
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
175
200
|
};
|
176
201
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
177
202
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
@@ -187,6 +212,15 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
187
212
|
{}
|
188
213
|
);
|
189
214
|
};
|
215
|
+
const getRetentionDays = () => {
|
216
|
+
const featureConfig = strapi2.ee.features.get("cms-content-history");
|
217
|
+
const licenseRetentionDays = typeof featureConfig === "object" && featureConfig?.options.retentionDays;
|
218
|
+
const userRetentionDays = strapi2.config.get("admin.history.retentionDays");
|
219
|
+
if (userRetentionDays && userRetentionDays < licenseRetentionDays) {
|
220
|
+
return userRetentionDays;
|
221
|
+
}
|
222
|
+
return Math.min(licenseRetentionDays, DEFAULT_RETENTION_DAYS);
|
223
|
+
};
|
190
224
|
const getVersionStatus = async (contentTypeUid, document) => {
|
191
225
|
const documentMetadataService = strapi2.plugin("content-manager").service("document-metadata");
|
192
226
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
@@ -228,80 +262,68 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
228
262
|
return acc;
|
229
263
|
}, {});
|
230
264
|
};
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
238
|
-
return next();
|
265
|
+
const buildMediaResponse = async (values) => {
|
266
|
+
return values.slice(0, 25).reduce(
|
267
|
+
async (currentRelationDataPromise, entry) => {
|
268
|
+
const currentRelationData = await currentRelationDataPromise;
|
269
|
+
if (!entry) {
|
270
|
+
return currentRelationData;
|
239
271
|
}
|
240
|
-
|
241
|
-
|
272
|
+
const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
|
273
|
+
if (relatedEntry) {
|
274
|
+
currentRelationData.results.push(relatedEntry);
|
275
|
+
} else {
|
276
|
+
currentRelationData.meta.missingCount += 1;
|
242
277
|
}
|
243
|
-
|
244
|
-
|
245
|
-
|
278
|
+
return currentRelationData;
|
279
|
+
},
|
280
|
+
Promise.resolve({
|
281
|
+
results: [],
|
282
|
+
meta: { missingCount: 0 }
|
283
|
+
})
|
284
|
+
);
|
285
|
+
};
|
286
|
+
const buildRelationReponse = async (values, attributeSchema) => {
|
287
|
+
return values.slice(0, 25).reduce(
|
288
|
+
async (currentRelationDataPromise, entry) => {
|
289
|
+
const currentRelationData = await currentRelationDataPromise;
|
290
|
+
if (!entry) {
|
291
|
+
return currentRelationData;
|
246
292
|
}
|
247
|
-
const
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
documentId: documentContext.documentId,
|
253
|
-
locale,
|
254
|
-
populate: getDeepPopulate2(contentTypeUid)
|
255
|
-
});
|
256
|
-
const status = await getVersionStatus(contentTypeUid, document);
|
257
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
258
|
-
const componentsSchemas = Object.keys(
|
259
|
-
attributesSchema
|
260
|
-
).reduce((currentComponentSchemas, key) => {
|
261
|
-
const fieldSchema = attributesSchema[key];
|
262
|
-
if (fieldSchema.type === "component") {
|
263
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
264
|
-
return {
|
265
|
-
...currentComponentSchemas,
|
266
|
-
[fieldSchema.component]: componentSchema
|
267
|
-
};
|
268
|
-
}
|
269
|
-
return currentComponentSchemas;
|
270
|
-
}, {});
|
271
|
-
await strapi2.db.transaction(async ({ onCommit }) => {
|
272
|
-
onCommit(() => {
|
273
|
-
this.createVersion({
|
274
|
-
contentType: contentTypeUid,
|
275
|
-
data: fp.omit(FIELDS_TO_IGNORE, document),
|
276
|
-
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
277
|
-
componentsSchemas,
|
278
|
-
relatedDocumentId: documentContext.documentId,
|
279
|
-
locale,
|
280
|
-
status
|
281
|
-
});
|
293
|
+
const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
|
294
|
+
if (relatedEntry) {
|
295
|
+
currentRelationData.results.push({
|
296
|
+
...relatedEntry,
|
297
|
+
status: await getVersionStatus(attributeSchema.target, relatedEntry)
|
282
298
|
});
|
283
|
-
}
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
299
|
+
} else {
|
300
|
+
currentRelationData.meta.missingCount += 1;
|
301
|
+
}
|
302
|
+
return currentRelationData;
|
303
|
+
},
|
304
|
+
Promise.resolve({
|
305
|
+
results: [],
|
306
|
+
meta: { missingCount: 0 }
|
307
|
+
})
|
308
|
+
);
|
309
|
+
};
|
310
|
+
return {
|
311
|
+
getSchemaAttributesDiff,
|
312
|
+
getRelationRestoreValue,
|
313
|
+
getMediaRestoreValue,
|
314
|
+
getDefaultLocale,
|
315
|
+
getLocaleDictionary,
|
316
|
+
getRetentionDays,
|
317
|
+
getVersionStatus,
|
318
|
+
getDeepPopulate: getDeepPopulate2,
|
319
|
+
buildMediaResponse,
|
320
|
+
buildRelationReponse
|
321
|
+
};
|
322
|
+
};
|
323
|
+
const createHistoryService = ({ strapi: strapi2 }) => {
|
324
|
+
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
325
|
+
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
326
|
+
return {
|
305
327
|
async createVersion(historyVersionData) {
|
306
328
|
await query.create({
|
307
329
|
data: {
|
@@ -312,7 +334,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
312
334
|
});
|
313
335
|
},
|
314
336
|
async findVersionsPage(params) {
|
315
|
-
const locale = params.query.locale || await getDefaultLocale();
|
337
|
+
const locale = params.query.locale || await serviceUtils.getDefaultLocale();
|
316
338
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
317
339
|
query.findPage({
|
318
340
|
...params.query,
|
@@ -326,78 +348,34 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
326
348
|
populate: ["createdBy"],
|
327
349
|
orderBy: [{ createdAt: "desc" }]
|
328
350
|
}),
|
329
|
-
getLocaleDictionary()
|
351
|
+
serviceUtils.getLocaleDictionary()
|
330
352
|
]);
|
331
|
-
const buildRelationReponse = async (values, attributeSchema) => {
|
332
|
-
return values.slice(0, 25).reduce(
|
333
|
-
async (currentRelationDataPromise, entry) => {
|
334
|
-
const currentRelationData = await currentRelationDataPromise;
|
335
|
-
if (!entry) {
|
336
|
-
return currentRelationData;
|
337
|
-
}
|
338
|
-
const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
|
339
|
-
const permissionChecker2 = getService$1("permission-checker").create({
|
340
|
-
userAbility: params.state.userAbility,
|
341
|
-
model: attributeSchema.target
|
342
|
-
});
|
343
|
-
const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
|
344
|
-
if (sanitizedEntry) {
|
345
|
-
currentRelationData.results.push({
|
346
|
-
...sanitizedEntry,
|
347
|
-
status: await getVersionStatus(attributeSchema.target, sanitizedEntry)
|
348
|
-
});
|
349
|
-
} else {
|
350
|
-
currentRelationData.meta.missingCount += 1;
|
351
|
-
}
|
352
|
-
return currentRelationData;
|
353
|
-
},
|
354
|
-
Promise.resolve({
|
355
|
-
results: [],
|
356
|
-
meta: { missingCount: 0 }
|
357
|
-
})
|
358
|
-
);
|
359
|
-
};
|
360
|
-
const buildMediaResponse = async (values) => {
|
361
|
-
return values.slice(0, 25).reduce(
|
362
|
-
async (currentRelationDataPromise, entry) => {
|
363
|
-
const currentRelationData = await currentRelationDataPromise;
|
364
|
-
if (!entry) {
|
365
|
-
return currentRelationData;
|
366
|
-
}
|
367
|
-
const permissionChecker2 = getService$1("permission-checker").create({
|
368
|
-
userAbility: params.state.userAbility,
|
369
|
-
model: "plugin::upload.file"
|
370
|
-
});
|
371
|
-
const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
|
372
|
-
const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
|
373
|
-
if (sanitizedEntry) {
|
374
|
-
currentRelationData.results.push(sanitizedEntry);
|
375
|
-
} else {
|
376
|
-
currentRelationData.meta.missingCount += 1;
|
377
|
-
}
|
378
|
-
return currentRelationData;
|
379
|
-
},
|
380
|
-
Promise.resolve({
|
381
|
-
results: [],
|
382
|
-
meta: { missingCount: 0 }
|
383
|
-
})
|
384
|
-
);
|
385
|
-
};
|
386
353
|
const populateEntryRelations = async (entry) => {
|
387
354
|
const entryWithRelations = await Object.entries(entry.schema).reduce(
|
388
355
|
async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
|
389
356
|
const attributeValue = entry.data[attributeKey];
|
390
357
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
391
358
|
if (attributeSchema.type === "media") {
|
359
|
+
const permissionChecker2 = getService$1("permission-checker").create({
|
360
|
+
userAbility: params.state.userAbility,
|
361
|
+
model: "plugin::upload.file"
|
362
|
+
});
|
363
|
+
const response = await serviceUtils.buildMediaResponse(attributeValues);
|
364
|
+
const sanitizedResults = await Promise.all(
|
365
|
+
response.results.map((media) => permissionChecker2.sanitizeOutput(media))
|
366
|
+
);
|
392
367
|
return {
|
393
368
|
...await currentDataWithRelations,
|
394
|
-
[attributeKey]:
|
369
|
+
[attributeKey]: {
|
370
|
+
results: sanitizedResults,
|
371
|
+
meta: response.meta
|
372
|
+
}
|
395
373
|
};
|
396
374
|
}
|
397
375
|
if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
|
398
376
|
if (attributeSchema.target === "admin::user") {
|
399
377
|
const adminUsers = await Promise.all(
|
400
|
-
attributeValues.map(
|
378
|
+
attributeValues.map((userToPopulate) => {
|
401
379
|
if (userToPopulate == null) {
|
402
380
|
return null;
|
403
381
|
}
|
@@ -414,9 +392,23 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
414
392
|
[attributeKey]: adminUsers
|
415
393
|
};
|
416
394
|
}
|
395
|
+
const permissionChecker2 = getService$1("permission-checker").create({
|
396
|
+
userAbility: params.state.userAbility,
|
397
|
+
model: attributeSchema.target
|
398
|
+
});
|
399
|
+
const response = await serviceUtils.buildRelationReponse(
|
400
|
+
attributeValues,
|
401
|
+
attributeSchema
|
402
|
+
);
|
403
|
+
const sanitizedResults = await Promise.all(
|
404
|
+
response.results.map((media) => permissionChecker2.sanitizeOutput(media))
|
405
|
+
);
|
417
406
|
return {
|
418
407
|
...await currentDataWithRelations,
|
419
|
-
[attributeKey]:
|
408
|
+
[attributeKey]: {
|
409
|
+
results: sanitizedResults,
|
410
|
+
meta: response.meta
|
411
|
+
}
|
420
412
|
};
|
421
413
|
}
|
422
414
|
return currentDataWithRelations;
|
@@ -431,7 +423,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
431
423
|
...result,
|
432
424
|
data: await populateEntryRelations(result),
|
433
425
|
meta: {
|
434
|
-
unknownAttributes: getSchemaAttributesDiff(
|
426
|
+
unknownAttributes: serviceUtils.getSchemaAttributesDiff(
|
435
427
|
result.schema,
|
436
428
|
strapi2.getModel(params.query.contentType).attributes
|
437
429
|
)
|
@@ -448,7 +440,10 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
448
440
|
async restoreVersion(versionId) {
|
449
441
|
const version = await query.findOne({ where: { id: versionId } });
|
450
442
|
const contentTypeSchemaAttributes = strapi2.getModel(version.contentType).attributes;
|
451
|
-
const schemaDiff = getSchemaAttributesDiff(
|
443
|
+
const schemaDiff = serviceUtils.getSchemaAttributesDiff(
|
444
|
+
version.schema,
|
445
|
+
contentTypeSchemaAttributes
|
446
|
+
);
|
452
447
|
const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(
|
453
448
|
(currentData, addedKey) => {
|
454
449
|
currentData[addedKey] = null;
|
@@ -461,61 +456,26 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
461
456
|
FIELDS_TO_IGNORE,
|
462
457
|
contentTypeSchemaAttributes
|
463
458
|
);
|
464
|
-
const
|
465
|
-
|
466
|
-
|
467
|
-
const
|
468
|
-
if (
|
459
|
+
const reducer = strapiUtils.async.reduce(Object.entries(sanitizedSchemaAttributes));
|
460
|
+
const dataWithoutMissingRelations = await reducer(
|
461
|
+
async (previousRelationAttributes, [name, attribute]) => {
|
462
|
+
const versionRelationData = version.data[name];
|
463
|
+
if (!versionRelationData) {
|
469
464
|
return previousRelationAttributes;
|
470
465
|
}
|
471
466
|
if (attribute.type === "relation" && // TODO: handle polymorphic relations
|
472
467
|
attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
|
473
|
-
|
474
|
-
|
475
|
-
return previousRelationAttributes;
|
476
|
-
const existingAndMissingRelations = await Promise.all(
|
477
|
-
relationData.map((relation) => {
|
478
|
-
return strapi2.documents(attribute.target).findOne({
|
479
|
-
documentId: relation.documentId,
|
480
|
-
locale: relation.locale || void 0
|
481
|
-
});
|
482
|
-
})
|
483
|
-
);
|
484
|
-
const existingRelations = existingAndMissingRelations.filter(
|
485
|
-
(relation) => relation !== null
|
486
|
-
);
|
487
|
-
previousRelationAttributes[name] = existingRelations;
|
488
|
-
} else {
|
489
|
-
const existingRelation = await strapi2.documents(attribute.target).findOne({
|
490
|
-
documentId: relationData.documentId,
|
491
|
-
locale: relationData.locale || void 0
|
492
|
-
});
|
493
|
-
if (!existingRelation) {
|
494
|
-
previousRelationAttributes[name] = null;
|
495
|
-
}
|
496
|
-
}
|
468
|
+
const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
|
469
|
+
previousRelationAttributes[name] = data2;
|
497
470
|
}
|
498
471
|
if (attribute.type === "media") {
|
499
|
-
|
500
|
-
|
501
|
-
// @ts-expect-error Fix the type definitions so this isn't any
|
502
|
-
relationData.map((media) => {
|
503
|
-
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
|
504
|
-
})
|
505
|
-
);
|
506
|
-
const existingMedias = existingAndMissingMedias.filter((media) => media != null);
|
507
|
-
previousRelationAttributes[name] = existingMedias;
|
508
|
-
} else {
|
509
|
-
const existingMedia = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: version.data[name].id } });
|
510
|
-
if (!existingMedia) {
|
511
|
-
previousRelationAttributes[name] = null;
|
512
|
-
}
|
513
|
-
}
|
472
|
+
const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
|
473
|
+
previousRelationAttributes[name] = data2;
|
514
474
|
}
|
515
475
|
return previousRelationAttributes;
|
516
476
|
},
|
517
477
|
// Clone to avoid mutating the original version data
|
518
|
-
|
478
|
+
structuredClone(dataWithoutAddedAttributes)
|
519
479
|
);
|
520
480
|
const data = fp.omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
|
521
481
|
const restoredDocument = await strapi2.documents(version.contentType).update({
|
@@ -530,8 +490,93 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
530
490
|
}
|
531
491
|
};
|
532
492
|
};
|
493
|
+
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
494
|
+
const state = {
|
495
|
+
deleteExpiredJob: null,
|
496
|
+
isInitialized: false
|
497
|
+
};
|
498
|
+
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
499
|
+
const historyService = getService(strapi2, "history");
|
500
|
+
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
501
|
+
return {
|
502
|
+
async bootstrap() {
|
503
|
+
if (state.isInitialized) {
|
504
|
+
return;
|
505
|
+
}
|
506
|
+
strapi2.documents.use(async (context, next) => {
|
507
|
+
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
508
|
+
return next();
|
509
|
+
}
|
510
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
511
|
+
return next();
|
512
|
+
}
|
513
|
+
const contentTypeUid = context.contentType.uid;
|
514
|
+
if (!contentTypeUid.startsWith("api::")) {
|
515
|
+
return next();
|
516
|
+
}
|
517
|
+
const result = await next();
|
518
|
+
const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
|
519
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
520
|
+
const locale = documentContext.locale || defaultLocale;
|
521
|
+
const document = await strapi2.documents(contentTypeUid).findOne({
|
522
|
+
documentId: documentContext.documentId,
|
523
|
+
locale,
|
524
|
+
populate: serviceUtils.getDeepPopulate(contentTypeUid)
|
525
|
+
});
|
526
|
+
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
527
|
+
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
528
|
+
const componentsSchemas = Object.keys(
|
529
|
+
attributesSchema
|
530
|
+
).reduce((currentComponentSchemas, key) => {
|
531
|
+
const fieldSchema = attributesSchema[key];
|
532
|
+
if (fieldSchema.type === "component") {
|
533
|
+
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
534
|
+
return {
|
535
|
+
...currentComponentSchemas,
|
536
|
+
[fieldSchema.component]: componentSchema
|
537
|
+
};
|
538
|
+
}
|
539
|
+
return currentComponentSchemas;
|
540
|
+
}, {});
|
541
|
+
await strapi2.db.transaction(async ({ onCommit }) => {
|
542
|
+
onCommit(() => {
|
543
|
+
historyService.createVersion({
|
544
|
+
contentType: contentTypeUid,
|
545
|
+
data: fp.omit(FIELDS_TO_IGNORE, document),
|
546
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
547
|
+
componentsSchemas,
|
548
|
+
relatedDocumentId: documentContext.documentId,
|
549
|
+
locale,
|
550
|
+
status
|
551
|
+
});
|
552
|
+
});
|
553
|
+
});
|
554
|
+
return result;
|
555
|
+
});
|
556
|
+
const retentionDays = serviceUtils.getRetentionDays();
|
557
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
558
|
+
const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
|
559
|
+
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
560
|
+
query.deleteMany({
|
561
|
+
where: {
|
562
|
+
created_at: {
|
563
|
+
$lt: expirationDate.toISOString()
|
564
|
+
}
|
565
|
+
}
|
566
|
+
});
|
567
|
+
});
|
568
|
+
state.isInitialized = true;
|
569
|
+
},
|
570
|
+
async destroy() {
|
571
|
+
if (state.deleteExpiredJob) {
|
572
|
+
state.deleteExpiredJob.cancel();
|
573
|
+
}
|
574
|
+
}
|
575
|
+
};
|
576
|
+
};
|
533
577
|
const services$1 = {
|
534
|
-
history: createHistoryService
|
578
|
+
history: createHistoryService,
|
579
|
+
lifecycles: createLifecyclesService
|
535
580
|
};
|
536
581
|
const info = { pluginName: "content-manager", type: "admin" };
|
537
582
|
const historyVersionRouter = {
|
@@ -611,10 +656,10 @@ const getFeature = () => {
|
|
611
656
|
strapi2.get("models").add(historyVersion);
|
612
657
|
},
|
613
658
|
bootstrap({ strapi: strapi2 }) {
|
614
|
-
getService(strapi2, "
|
659
|
+
getService(strapi2, "lifecycles").bootstrap();
|
615
660
|
},
|
616
661
|
destroy({ strapi: strapi2 }) {
|
617
|
-
getService(strapi2, "
|
662
|
+
getService(strapi2, "lifecycles").destroy();
|
618
663
|
},
|
619
664
|
controllers: controllers$1,
|
620
665
|
services: services$1,
|