@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.mjs
CHANGED
@@ -112,40 +112,65 @@ const FIELDS_TO_IGNORE = [
|
|
112
112
|
"strapi_stage",
|
113
113
|
"strapi_assignee"
|
114
114
|
];
|
115
|
-
const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
|
116
|
-
const sanitizedContentTypeSchemaAttributes = omit(FIELDS_TO_IGNORE, contentTypeSchemaAttributes);
|
117
|
-
const reduceDifferenceToAttributesObject = (diffKeys, source) => {
|
118
|
-
return diffKeys.reduce((previousAttributesObject, diffKey) => {
|
119
|
-
previousAttributesObject[diffKey] = source[diffKey];
|
120
|
-
return previousAttributesObject;
|
121
|
-
}, {});
|
122
|
-
};
|
123
|
-
const versionSchemaKeys = Object.keys(versionSchemaAttributes);
|
124
|
-
const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
|
125
|
-
const uniqueToContentType = difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
|
126
|
-
const added = reduceDifferenceToAttributesObject(
|
127
|
-
uniqueToContentType,
|
128
|
-
sanitizedContentTypeSchemaAttributes
|
129
|
-
);
|
130
|
-
const uniqueToVersion = difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
|
131
|
-
const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
|
132
|
-
return { added, removed };
|
133
|
-
};
|
134
115
|
const DEFAULT_RETENTION_DAYS = 90;
|
135
|
-
const
|
136
|
-
const
|
137
|
-
|
138
|
-
|
116
|
+
const createServiceUtils = ({ strapi: strapi2 }) => {
|
117
|
+
const getSchemaAttributesDiff = (versionSchemaAttributes, contentTypeSchemaAttributes) => {
|
118
|
+
const sanitizedContentTypeSchemaAttributes = omit(
|
119
|
+
FIELDS_TO_IGNORE,
|
120
|
+
contentTypeSchemaAttributes
|
121
|
+
);
|
122
|
+
const reduceDifferenceToAttributesObject = (diffKeys, source) => {
|
123
|
+
return diffKeys.reduce(
|
124
|
+
(previousAttributesObject, diffKey) => {
|
125
|
+
previousAttributesObject[diffKey] = source[diffKey];
|
126
|
+
return previousAttributesObject;
|
127
|
+
},
|
128
|
+
{}
|
129
|
+
);
|
130
|
+
};
|
131
|
+
const versionSchemaKeys = Object.keys(versionSchemaAttributes);
|
132
|
+
const contentTypeSchemaAttributesKeys = Object.keys(sanitizedContentTypeSchemaAttributes);
|
133
|
+
const uniqueToContentType = difference(contentTypeSchemaAttributesKeys, versionSchemaKeys);
|
134
|
+
const added = reduceDifferenceToAttributesObject(
|
135
|
+
uniqueToContentType,
|
136
|
+
sanitizedContentTypeSchemaAttributes
|
137
|
+
);
|
138
|
+
const uniqueToVersion = difference(versionSchemaKeys, contentTypeSchemaAttributesKeys);
|
139
|
+
const removed = reduceDifferenceToAttributesObject(uniqueToVersion, versionSchemaAttributes);
|
140
|
+
return { added, removed };
|
139
141
|
};
|
140
|
-
const
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
142
|
+
const getRelationRestoreValue = async (versionRelationData, attribute) => {
|
143
|
+
if (Array.isArray(versionRelationData)) {
|
144
|
+
if (versionRelationData.length === 0)
|
145
|
+
return versionRelationData;
|
146
|
+
const existingAndMissingRelations = await Promise.all(
|
147
|
+
versionRelationData.map((relation) => {
|
148
|
+
return strapi2.documents(attribute.target).findOne({
|
149
|
+
documentId: relation.documentId,
|
150
|
+
locale: relation.locale || void 0
|
151
|
+
});
|
152
|
+
})
|
153
|
+
);
|
154
|
+
return existingAndMissingRelations.filter(
|
155
|
+
(relation) => relation !== null
|
156
|
+
);
|
147
157
|
}
|
148
|
-
return
|
158
|
+
return strapi2.documents(attribute.target).findOne({
|
159
|
+
documentId: versionRelationData.documentId,
|
160
|
+
locale: versionRelationData.locale || void 0
|
161
|
+
});
|
162
|
+
};
|
163
|
+
const getMediaRestoreValue = async (versionRelationData, attribute) => {
|
164
|
+
if (attribute.multiple) {
|
165
|
+
const existingAndMissingMedias = await Promise.all(
|
166
|
+
// @ts-expect-error Fix the type definitions so this isn't any
|
167
|
+
versionRelationData.map((media) => {
|
168
|
+
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
|
169
|
+
})
|
170
|
+
);
|
171
|
+
return existingAndMissingMedias.filter((media) => media != null);
|
172
|
+
}
|
173
|
+
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
149
174
|
};
|
150
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
151
176
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
@@ -161,6 +186,15 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
161
186
|
{}
|
162
187
|
);
|
163
188
|
};
|
189
|
+
const getRetentionDays = () => {
|
190
|
+
const featureConfig = strapi2.ee.features.get("cms-content-history");
|
191
|
+
const licenseRetentionDays = typeof featureConfig === "object" && featureConfig?.options.retentionDays;
|
192
|
+
const userRetentionDays = strapi2.config.get("admin.history.retentionDays");
|
193
|
+
if (userRetentionDays && userRetentionDays < licenseRetentionDays) {
|
194
|
+
return userRetentionDays;
|
195
|
+
}
|
196
|
+
return Math.min(licenseRetentionDays, DEFAULT_RETENTION_DAYS);
|
197
|
+
};
|
164
198
|
const getVersionStatus = async (contentTypeUid, document) => {
|
165
199
|
const documentMetadataService = strapi2.plugin("content-manager").service("document-metadata");
|
166
200
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
@@ -202,80 +236,68 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
202
236
|
return acc;
|
203
237
|
}, {});
|
204
238
|
};
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
212
|
-
return next();
|
239
|
+
const buildMediaResponse = async (values) => {
|
240
|
+
return values.slice(0, 25).reduce(
|
241
|
+
async (currentRelationDataPromise, entry) => {
|
242
|
+
const currentRelationData = await currentRelationDataPromise;
|
243
|
+
if (!entry) {
|
244
|
+
return currentRelationData;
|
213
245
|
}
|
214
|
-
|
215
|
-
|
246
|
+
const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
|
247
|
+
if (relatedEntry) {
|
248
|
+
currentRelationData.results.push(relatedEntry);
|
249
|
+
} else {
|
250
|
+
currentRelationData.meta.missingCount += 1;
|
216
251
|
}
|
217
|
-
|
218
|
-
|
219
|
-
|
252
|
+
return currentRelationData;
|
253
|
+
},
|
254
|
+
Promise.resolve({
|
255
|
+
results: [],
|
256
|
+
meta: { missingCount: 0 }
|
257
|
+
})
|
258
|
+
);
|
259
|
+
};
|
260
|
+
const buildRelationReponse = async (values, attributeSchema) => {
|
261
|
+
return values.slice(0, 25).reduce(
|
262
|
+
async (currentRelationDataPromise, entry) => {
|
263
|
+
const currentRelationData = await currentRelationDataPromise;
|
264
|
+
if (!entry) {
|
265
|
+
return currentRelationData;
|
220
266
|
}
|
221
|
-
const
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
documentId: documentContext.documentId,
|
227
|
-
locale,
|
228
|
-
populate: getDeepPopulate2(contentTypeUid)
|
229
|
-
});
|
230
|
-
const status = await getVersionStatus(contentTypeUid, document);
|
231
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
232
|
-
const componentsSchemas = Object.keys(
|
233
|
-
attributesSchema
|
234
|
-
).reduce((currentComponentSchemas, key) => {
|
235
|
-
const fieldSchema = attributesSchema[key];
|
236
|
-
if (fieldSchema.type === "component") {
|
237
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
238
|
-
return {
|
239
|
-
...currentComponentSchemas,
|
240
|
-
[fieldSchema.component]: componentSchema
|
241
|
-
};
|
242
|
-
}
|
243
|
-
return currentComponentSchemas;
|
244
|
-
}, {});
|
245
|
-
await strapi2.db.transaction(async ({ onCommit }) => {
|
246
|
-
onCommit(() => {
|
247
|
-
this.createVersion({
|
248
|
-
contentType: contentTypeUid,
|
249
|
-
data: omit(FIELDS_TO_IGNORE, document),
|
250
|
-
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
251
|
-
componentsSchemas,
|
252
|
-
relatedDocumentId: documentContext.documentId,
|
253
|
-
locale,
|
254
|
-
status
|
255
|
-
});
|
267
|
+
const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
|
268
|
+
if (relatedEntry) {
|
269
|
+
currentRelationData.results.push({
|
270
|
+
...relatedEntry,
|
271
|
+
status: await getVersionStatus(attributeSchema.target, relatedEntry)
|
256
272
|
});
|
257
|
-
}
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
273
|
+
} else {
|
274
|
+
currentRelationData.meta.missingCount += 1;
|
275
|
+
}
|
276
|
+
return currentRelationData;
|
277
|
+
},
|
278
|
+
Promise.resolve({
|
279
|
+
results: [],
|
280
|
+
meta: { missingCount: 0 }
|
281
|
+
})
|
282
|
+
);
|
283
|
+
};
|
284
|
+
return {
|
285
|
+
getSchemaAttributesDiff,
|
286
|
+
getRelationRestoreValue,
|
287
|
+
getMediaRestoreValue,
|
288
|
+
getDefaultLocale,
|
289
|
+
getLocaleDictionary,
|
290
|
+
getRetentionDays,
|
291
|
+
getVersionStatus,
|
292
|
+
getDeepPopulate: getDeepPopulate2,
|
293
|
+
buildMediaResponse,
|
294
|
+
buildRelationReponse
|
295
|
+
};
|
296
|
+
};
|
297
|
+
const createHistoryService = ({ strapi: strapi2 }) => {
|
298
|
+
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
299
|
+
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
300
|
+
return {
|
279
301
|
async createVersion(historyVersionData) {
|
280
302
|
await query.create({
|
281
303
|
data: {
|
@@ -286,7 +308,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
286
308
|
});
|
287
309
|
},
|
288
310
|
async findVersionsPage(params) {
|
289
|
-
const locale = params.query.locale || await getDefaultLocale();
|
311
|
+
const locale = params.query.locale || await serviceUtils.getDefaultLocale();
|
290
312
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
291
313
|
query.findPage({
|
292
314
|
...params.query,
|
@@ -300,78 +322,34 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
300
322
|
populate: ["createdBy"],
|
301
323
|
orderBy: [{ createdAt: "desc" }]
|
302
324
|
}),
|
303
|
-
getLocaleDictionary()
|
325
|
+
serviceUtils.getLocaleDictionary()
|
304
326
|
]);
|
305
|
-
const buildRelationReponse = async (values, attributeSchema) => {
|
306
|
-
return values.slice(0, 25).reduce(
|
307
|
-
async (currentRelationDataPromise, entry) => {
|
308
|
-
const currentRelationData = await currentRelationDataPromise;
|
309
|
-
if (!entry) {
|
310
|
-
return currentRelationData;
|
311
|
-
}
|
312
|
-
const relatedEntry = await strapi2.documents(attributeSchema.target).findOne({ documentId: entry.documentId, locale: entry.locale || void 0 });
|
313
|
-
const permissionChecker2 = getService$1("permission-checker").create({
|
314
|
-
userAbility: params.state.userAbility,
|
315
|
-
model: attributeSchema.target
|
316
|
-
});
|
317
|
-
const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
|
318
|
-
if (sanitizedEntry) {
|
319
|
-
currentRelationData.results.push({
|
320
|
-
...sanitizedEntry,
|
321
|
-
status: await getVersionStatus(attributeSchema.target, sanitizedEntry)
|
322
|
-
});
|
323
|
-
} else {
|
324
|
-
currentRelationData.meta.missingCount += 1;
|
325
|
-
}
|
326
|
-
return currentRelationData;
|
327
|
-
},
|
328
|
-
Promise.resolve({
|
329
|
-
results: [],
|
330
|
-
meta: { missingCount: 0 }
|
331
|
-
})
|
332
|
-
);
|
333
|
-
};
|
334
|
-
const buildMediaResponse = async (values) => {
|
335
|
-
return values.slice(0, 25).reduce(
|
336
|
-
async (currentRelationDataPromise, entry) => {
|
337
|
-
const currentRelationData = await currentRelationDataPromise;
|
338
|
-
if (!entry) {
|
339
|
-
return currentRelationData;
|
340
|
-
}
|
341
|
-
const permissionChecker2 = getService$1("permission-checker").create({
|
342
|
-
userAbility: params.state.userAbility,
|
343
|
-
model: "plugin::upload.file"
|
344
|
-
});
|
345
|
-
const relatedEntry = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: entry.id } });
|
346
|
-
const sanitizedEntry = await permissionChecker2.sanitizeOutput(relatedEntry);
|
347
|
-
if (sanitizedEntry) {
|
348
|
-
currentRelationData.results.push(sanitizedEntry);
|
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
327
|
const populateEntryRelations = async (entry) => {
|
361
328
|
const entryWithRelations = await Object.entries(entry.schema).reduce(
|
362
329
|
async (currentDataWithRelations, [attributeKey, attributeSchema]) => {
|
363
330
|
const attributeValue = entry.data[attributeKey];
|
364
331
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
365
332
|
if (attributeSchema.type === "media") {
|
333
|
+
const permissionChecker2 = getService$1("permission-checker").create({
|
334
|
+
userAbility: params.state.userAbility,
|
335
|
+
model: "plugin::upload.file"
|
336
|
+
});
|
337
|
+
const response = await serviceUtils.buildMediaResponse(attributeValues);
|
338
|
+
const sanitizedResults = await Promise.all(
|
339
|
+
response.results.map((media) => permissionChecker2.sanitizeOutput(media))
|
340
|
+
);
|
366
341
|
return {
|
367
342
|
...await currentDataWithRelations,
|
368
|
-
[attributeKey]:
|
343
|
+
[attributeKey]: {
|
344
|
+
results: sanitizedResults,
|
345
|
+
meta: response.meta
|
346
|
+
}
|
369
347
|
};
|
370
348
|
}
|
371
349
|
if (attributeSchema.type === "relation" && attributeSchema.relation !== "morphToOne" && attributeSchema.relation !== "morphToMany") {
|
372
350
|
if (attributeSchema.target === "admin::user") {
|
373
351
|
const adminUsers = await Promise.all(
|
374
|
-
attributeValues.map(
|
352
|
+
attributeValues.map((userToPopulate) => {
|
375
353
|
if (userToPopulate == null) {
|
376
354
|
return null;
|
377
355
|
}
|
@@ -388,9 +366,23 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
388
366
|
[attributeKey]: adminUsers
|
389
367
|
};
|
390
368
|
}
|
369
|
+
const permissionChecker2 = getService$1("permission-checker").create({
|
370
|
+
userAbility: params.state.userAbility,
|
371
|
+
model: attributeSchema.target
|
372
|
+
});
|
373
|
+
const response = await serviceUtils.buildRelationReponse(
|
374
|
+
attributeValues,
|
375
|
+
attributeSchema
|
376
|
+
);
|
377
|
+
const sanitizedResults = await Promise.all(
|
378
|
+
response.results.map((media) => permissionChecker2.sanitizeOutput(media))
|
379
|
+
);
|
391
380
|
return {
|
392
381
|
...await currentDataWithRelations,
|
393
|
-
[attributeKey]:
|
382
|
+
[attributeKey]: {
|
383
|
+
results: sanitizedResults,
|
384
|
+
meta: response.meta
|
385
|
+
}
|
394
386
|
};
|
395
387
|
}
|
396
388
|
return currentDataWithRelations;
|
@@ -405,7 +397,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
405
397
|
...result,
|
406
398
|
data: await populateEntryRelations(result),
|
407
399
|
meta: {
|
408
|
-
unknownAttributes: getSchemaAttributesDiff(
|
400
|
+
unknownAttributes: serviceUtils.getSchemaAttributesDiff(
|
409
401
|
result.schema,
|
410
402
|
strapi2.getModel(params.query.contentType).attributes
|
411
403
|
)
|
@@ -422,7 +414,10 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
422
414
|
async restoreVersion(versionId) {
|
423
415
|
const version = await query.findOne({ where: { id: versionId } });
|
424
416
|
const contentTypeSchemaAttributes = strapi2.getModel(version.contentType).attributes;
|
425
|
-
const schemaDiff = getSchemaAttributesDiff(
|
417
|
+
const schemaDiff = serviceUtils.getSchemaAttributesDiff(
|
418
|
+
version.schema,
|
419
|
+
contentTypeSchemaAttributes
|
420
|
+
);
|
426
421
|
const dataWithoutAddedAttributes = Object.keys(schemaDiff.added).reduce(
|
427
422
|
(currentData, addedKey) => {
|
428
423
|
currentData[addedKey] = null;
|
@@ -435,61 +430,26 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
435
430
|
FIELDS_TO_IGNORE,
|
436
431
|
contentTypeSchemaAttributes
|
437
432
|
);
|
438
|
-
const
|
439
|
-
|
440
|
-
|
441
|
-
const
|
442
|
-
if (
|
433
|
+
const reducer = async.reduce(Object.entries(sanitizedSchemaAttributes));
|
434
|
+
const dataWithoutMissingRelations = await reducer(
|
435
|
+
async (previousRelationAttributes, [name, attribute]) => {
|
436
|
+
const versionRelationData = version.data[name];
|
437
|
+
if (!versionRelationData) {
|
443
438
|
return previousRelationAttributes;
|
444
439
|
}
|
445
440
|
if (attribute.type === "relation" && // TODO: handle polymorphic relations
|
446
441
|
attribute.relation !== "morphToOne" && attribute.relation !== "morphToMany") {
|
447
|
-
|
448
|
-
|
449
|
-
return previousRelationAttributes;
|
450
|
-
const existingAndMissingRelations = await Promise.all(
|
451
|
-
relationData.map((relation) => {
|
452
|
-
return strapi2.documents(attribute.target).findOne({
|
453
|
-
documentId: relation.documentId,
|
454
|
-
locale: relation.locale || void 0
|
455
|
-
});
|
456
|
-
})
|
457
|
-
);
|
458
|
-
const existingRelations = existingAndMissingRelations.filter(
|
459
|
-
(relation) => relation !== null
|
460
|
-
);
|
461
|
-
previousRelationAttributes[name] = existingRelations;
|
462
|
-
} else {
|
463
|
-
const existingRelation = await strapi2.documents(attribute.target).findOne({
|
464
|
-
documentId: relationData.documentId,
|
465
|
-
locale: relationData.locale || void 0
|
466
|
-
});
|
467
|
-
if (!existingRelation) {
|
468
|
-
previousRelationAttributes[name] = null;
|
469
|
-
}
|
470
|
-
}
|
442
|
+
const data2 = await serviceUtils.getRelationRestoreValue(versionRelationData, attribute);
|
443
|
+
previousRelationAttributes[name] = data2;
|
471
444
|
}
|
472
445
|
if (attribute.type === "media") {
|
473
|
-
|
474
|
-
|
475
|
-
// @ts-expect-error Fix the type definitions so this isn't any
|
476
|
-
relationData.map((media) => {
|
477
|
-
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: media.id } });
|
478
|
-
})
|
479
|
-
);
|
480
|
-
const existingMedias = existingAndMissingMedias.filter((media) => media != null);
|
481
|
-
previousRelationAttributes[name] = existingMedias;
|
482
|
-
} else {
|
483
|
-
const existingMedia = await strapi2.db.query("plugin::upload.file").findOne({ where: { id: version.data[name].id } });
|
484
|
-
if (!existingMedia) {
|
485
|
-
previousRelationAttributes[name] = null;
|
486
|
-
}
|
487
|
-
}
|
446
|
+
const data2 = await serviceUtils.getMediaRestoreValue(versionRelationData, attribute);
|
447
|
+
previousRelationAttributes[name] = data2;
|
488
448
|
}
|
489
449
|
return previousRelationAttributes;
|
490
450
|
},
|
491
451
|
// Clone to avoid mutating the original version data
|
492
|
-
|
452
|
+
structuredClone(dataWithoutAddedAttributes)
|
493
453
|
);
|
494
454
|
const data = omit(["id", ...Object.keys(schemaDiff.removed)], dataWithoutMissingRelations);
|
495
455
|
const restoredDocument = await strapi2.documents(version.contentType).update({
|
@@ -504,8 +464,93 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
504
464
|
}
|
505
465
|
};
|
506
466
|
};
|
467
|
+
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
468
|
+
const state = {
|
469
|
+
deleteExpiredJob: null,
|
470
|
+
isInitialized: false
|
471
|
+
};
|
472
|
+
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
473
|
+
const historyService = getService(strapi2, "history");
|
474
|
+
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
475
|
+
return {
|
476
|
+
async bootstrap() {
|
477
|
+
if (state.isInitialized) {
|
478
|
+
return;
|
479
|
+
}
|
480
|
+
strapi2.documents.use(async (context, next) => {
|
481
|
+
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
482
|
+
return next();
|
483
|
+
}
|
484
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
485
|
+
return next();
|
486
|
+
}
|
487
|
+
const contentTypeUid = context.contentType.uid;
|
488
|
+
if (!contentTypeUid.startsWith("api::")) {
|
489
|
+
return next();
|
490
|
+
}
|
491
|
+
const result = await next();
|
492
|
+
const documentContext = context.action === "create" ? { documentId: result.documentId, locale: context.params?.locale } : { documentId: context.params.documentId, locale: context.params?.locale };
|
493
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
494
|
+
const locale = documentContext.locale || defaultLocale;
|
495
|
+
const document = await strapi2.documents(contentTypeUid).findOne({
|
496
|
+
documentId: documentContext.documentId,
|
497
|
+
locale,
|
498
|
+
populate: serviceUtils.getDeepPopulate(contentTypeUid)
|
499
|
+
});
|
500
|
+
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
501
|
+
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
502
|
+
const componentsSchemas = Object.keys(
|
503
|
+
attributesSchema
|
504
|
+
).reduce((currentComponentSchemas, key) => {
|
505
|
+
const fieldSchema = attributesSchema[key];
|
506
|
+
if (fieldSchema.type === "component") {
|
507
|
+
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
508
|
+
return {
|
509
|
+
...currentComponentSchemas,
|
510
|
+
[fieldSchema.component]: componentSchema
|
511
|
+
};
|
512
|
+
}
|
513
|
+
return currentComponentSchemas;
|
514
|
+
}, {});
|
515
|
+
await strapi2.db.transaction(async ({ onCommit }) => {
|
516
|
+
onCommit(() => {
|
517
|
+
historyService.createVersion({
|
518
|
+
contentType: contentTypeUid,
|
519
|
+
data: omit(FIELDS_TO_IGNORE, document),
|
520
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
521
|
+
componentsSchemas,
|
522
|
+
relatedDocumentId: documentContext.documentId,
|
523
|
+
locale,
|
524
|
+
status
|
525
|
+
});
|
526
|
+
});
|
527
|
+
});
|
528
|
+
return result;
|
529
|
+
});
|
530
|
+
const retentionDays = serviceUtils.getRetentionDays();
|
531
|
+
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
532
|
+
const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
|
533
|
+
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
534
|
+
query.deleteMany({
|
535
|
+
where: {
|
536
|
+
created_at: {
|
537
|
+
$lt: expirationDate.toISOString()
|
538
|
+
}
|
539
|
+
}
|
540
|
+
});
|
541
|
+
});
|
542
|
+
state.isInitialized = true;
|
543
|
+
},
|
544
|
+
async destroy() {
|
545
|
+
if (state.deleteExpiredJob) {
|
546
|
+
state.deleteExpiredJob.cancel();
|
547
|
+
}
|
548
|
+
}
|
549
|
+
};
|
550
|
+
};
|
507
551
|
const services$1 = {
|
508
|
-
history: createHistoryService
|
552
|
+
history: createHistoryService,
|
553
|
+
lifecycles: createLifecyclesService
|
509
554
|
};
|
510
555
|
const info = { pluginName: "content-manager", type: "admin" };
|
511
556
|
const historyVersionRouter = {
|
@@ -585,10 +630,10 @@ const getFeature = () => {
|
|
585
630
|
strapi2.get("models").add(historyVersion);
|
586
631
|
},
|
587
632
|
bootstrap({ strapi: strapi2 }) {
|
588
|
-
getService(strapi2, "
|
633
|
+
getService(strapi2, "lifecycles").bootstrap();
|
589
634
|
},
|
590
635
|
destroy({ strapi: strapi2 }) {
|
591
|
-
getService(strapi2, "
|
636
|
+
getService(strapi2, "lifecycles").destroy();
|
592
637
|
},
|
593
638
|
controllers: controllers$1,
|
594
639
|
services: services$1,
|