@rmdes/indiekit-endpoint-posts 1.0.0-beta.42 → 1.0.0-beta.44
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/index.js +4 -0
- package/lib/controllers/form.js +9 -0
- package/lib/controllers/posts.js +9 -0
- package/lib/controllers/purge-all.js +68 -0
- package/lib/utils.js +18 -0
- package/locales/en.json +9 -0
- package/package.json +1 -1
- package/views/post-form.njk +2 -2
- package/views/post-purge-all.njk +20 -0
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import express from "express";
|
|
|
6
6
|
|
|
7
7
|
import { deleteController } from "./lib/controllers/delete.js";
|
|
8
8
|
import { editController } from "./lib/controllers/edit.js";
|
|
9
|
+
import { purgeAllController } from "./lib/controllers/purge-all.js";
|
|
9
10
|
import { purgeController } from "./lib/controllers/purge.js";
|
|
10
11
|
import { formController } from "./lib/controllers/form.js";
|
|
11
12
|
import { newController } from "./lib/controllers/new.js";
|
|
@@ -47,6 +48,9 @@ export default class PostsEndpoint {
|
|
|
47
48
|
|
|
48
49
|
router.get("/edit", editController.get);
|
|
49
50
|
|
|
51
|
+
router.get("/purge-deleted", purgeAllController.get);
|
|
52
|
+
router.post("/purge-deleted", purgeAllController.post);
|
|
53
|
+
|
|
50
54
|
router.get("/new", newController.get);
|
|
51
55
|
router.post("/new", validate.new, newController.post);
|
|
52
56
|
|
package/lib/controllers/form.js
CHANGED
|
@@ -85,6 +85,15 @@ export const formController = {
|
|
|
85
85
|
delete values.postType;
|
|
86
86
|
delete values["publication-date"];
|
|
87
87
|
|
|
88
|
+
// Map content-warning text to summary when post is marked sensitive
|
|
89
|
+
// and the post type doesn't have its own summary field
|
|
90
|
+
if (values.sensitive && values["content-warning"]) {
|
|
91
|
+
if (!values.summary) {
|
|
92
|
+
values.summary = values["content-warning"];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
delete values["content-warning"];
|
|
96
|
+
|
|
88
97
|
// Easy MDE appends `image` value to formData for last image uploaded
|
|
89
98
|
delete values.image;
|
|
90
99
|
|
package/lib/controllers/posts.js
CHANGED
|
@@ -62,6 +62,7 @@ export const postsController = async (request, response, next) => {
|
|
|
62
62
|
item.icon = item["post-type"];
|
|
63
63
|
item.locale = application.locale;
|
|
64
64
|
item.photo = getPhotoUrl(publication, item);
|
|
65
|
+
|
|
65
66
|
item.description = {
|
|
66
67
|
text:
|
|
67
68
|
item.summary ||
|
|
@@ -111,6 +112,14 @@ export const postsController = async (request, response, next) => {
|
|
|
111
112
|
text: response.locals.__("posts.create.action"),
|
|
112
113
|
}
|
|
113
114
|
: {},
|
|
115
|
+
scope && checkScope(scope, "delete") && status === "deleted" && total > 0
|
|
116
|
+
? {
|
|
117
|
+
classes: "actions__link--warning",
|
|
118
|
+
href: path.join(request.baseUrl, "/purge-deleted"),
|
|
119
|
+
icon: "delete",
|
|
120
|
+
text: response.locals.__("posts.purgeAll.action"),
|
|
121
|
+
}
|
|
122
|
+
: {},
|
|
114
123
|
],
|
|
115
124
|
cursor,
|
|
116
125
|
posts,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { checkScope } from "@indiekit/endpoint-micropub/lib/scope.js";
|
|
2
|
+
|
|
3
|
+
import { getPosts, purgeAllDeletedPosts } from "../utils.js";
|
|
4
|
+
|
|
5
|
+
export const purgeAllController = {
|
|
6
|
+
/**
|
|
7
|
+
* Confirm purge of all deleted posts
|
|
8
|
+
* @type {import("express").RequestHandler}
|
|
9
|
+
*/
|
|
10
|
+
async get(request, response) {
|
|
11
|
+
const { application } = request.app.locals;
|
|
12
|
+
const { scope } = request.session;
|
|
13
|
+
|
|
14
|
+
if (!scope || !checkScope(scope, "delete")) {
|
|
15
|
+
return response.redirect(request.baseUrl);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Count deleted posts for the confirmation message
|
|
19
|
+
const { total } = await getPosts(application, { status: "deleted" });
|
|
20
|
+
|
|
21
|
+
if (total === 0) {
|
|
22
|
+
const message = encodeURIComponent(
|
|
23
|
+
response.locals.__("posts.purgeAll.none"),
|
|
24
|
+
);
|
|
25
|
+
return response.redirect(`${request.baseUrl}?success=${message}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
response.render("post-purge-all", {
|
|
29
|
+
title: response.locals.__("posts.purgeAll.title"),
|
|
30
|
+
deletedCount: total,
|
|
31
|
+
postsPath: request.baseUrl,
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Permanently delete all soft-deleted posts
|
|
37
|
+
* @type {import("express").RequestHandler}
|
|
38
|
+
*/
|
|
39
|
+
async post(request, response) {
|
|
40
|
+
const { application } = request.app.locals;
|
|
41
|
+
const { scope } = request.session;
|
|
42
|
+
|
|
43
|
+
if (!scope || !checkScope(scope, "delete")) {
|
|
44
|
+
return response.redirect(request.baseUrl);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const deletedCount = await purgeAllDeletedPosts(application);
|
|
49
|
+
|
|
50
|
+
const message = encodeURIComponent(
|
|
51
|
+
response.locals.__("posts.purgeAll.success", deletedCount),
|
|
52
|
+
);
|
|
53
|
+
response.redirect(`${request.baseUrl}?success=${message}`);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
const { total } = await getPosts(application, {
|
|
56
|
+
status: "deleted",
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
response.status(error.status || 500);
|
|
60
|
+
response.render("post-purge-all", {
|
|
61
|
+
title: response.locals.__("posts.purgeAll.title"),
|
|
62
|
+
deletedCount: total,
|
|
63
|
+
postsPath: request.baseUrl,
|
|
64
|
+
error,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
package/lib/utils.js
CHANGED
|
@@ -307,6 +307,24 @@ export const purgePost = async (uid, application) => {
|
|
|
307
307
|
return result.deletedCount > 0;
|
|
308
308
|
};
|
|
309
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Permanently delete all soft-deleted posts from MongoDB
|
|
312
|
+
* @param {object} application - Application object with collections
|
|
313
|
+
* @returns {Promise<number>} Number of posts deleted
|
|
314
|
+
*/
|
|
315
|
+
export const purgeAllDeletedPosts = async (application) => {
|
|
316
|
+
const postsCollection = application?.collections?.get("posts");
|
|
317
|
+
if (!postsCollection) {
|
|
318
|
+
return 0;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const result = await postsCollection.deleteMany({
|
|
322
|
+
"properties.deleted": { $exists: true },
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
return result.deletedCount;
|
|
326
|
+
};
|
|
327
|
+
|
|
310
328
|
/**
|
|
311
329
|
* Query database for post data by Micropub URL
|
|
312
330
|
* @param {string} url - Micropub URL (e.g. https://example.com/articles/2026/02/13/slug)
|
package/locales/en.json
CHANGED
|
@@ -62,6 +62,15 @@
|
|
|
62
62
|
"cancel": "No – return to posts",
|
|
63
63
|
"success": "Post permanently deleted"
|
|
64
64
|
},
|
|
65
|
+
"purgeAll": {
|
|
66
|
+
"action": "Purge all deleted",
|
|
67
|
+
"title": "Permanently delete all deleted posts?",
|
|
68
|
+
"warning": "This will permanently remove **%s deleted post(s)** from the database. This action cannot be undone.",
|
|
69
|
+
"submit": "I'm sure - permanently delete all",
|
|
70
|
+
"cancel": "No - return to posts",
|
|
71
|
+
"success": "Permanently deleted %s post(s)",
|
|
72
|
+
"none": "No deleted posts to purge"
|
|
73
|
+
},
|
|
65
74
|
"form": {
|
|
66
75
|
"advancedOptions": "Advanced options",
|
|
67
76
|
"back": "Change post type",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmdes/indiekit-endpoint-posts",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.44",
|
|
4
4
|
"description": "Post management endpoint for Indiekit with syndicate form fix. View posts published by your Micropub endpoint and publish new posts to it.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indiekit",
|
package/views/post-form.njk
CHANGED
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
label: __("posts.form.sensitive.hint"),
|
|
83
83
|
value: "true",
|
|
84
84
|
conditional: input({
|
|
85
|
-
name: "
|
|
86
|
-
value: properties
|
|
85
|
+
name: "content-warning",
|
|
86
|
+
value: properties["content-warning"],
|
|
87
87
|
label: __("posts.form.summary.label"),
|
|
88
88
|
optional: true
|
|
89
89
|
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{% extends "form.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block form %}
|
|
4
|
+
{{ heading({
|
|
5
|
+
text: title
|
|
6
|
+
}) }}
|
|
7
|
+
|
|
8
|
+
{{ prose({
|
|
9
|
+
text: __("posts.purgeAll.warning", deletedCount)
|
|
10
|
+
}) }}
|
|
11
|
+
|
|
12
|
+
{{ button({
|
|
13
|
+
classes: "button--warning",
|
|
14
|
+
text: __("posts.purgeAll.submit")
|
|
15
|
+
}) }}
|
|
16
|
+
|
|
17
|
+
{{ prose({
|
|
18
|
+
text: "[" + __("posts.purgeAll.cancel") + "](" + postsPath + ")"
|
|
19
|
+
}) }}
|
|
20
|
+
{% endblock %}
|