@the-starport/nodebb-plugin-mdx-page-renderer 1.0.0 → 1.0.1
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/lib/controllers.js +31 -11
- package/lib/sources.js +26 -3
- package/lib/utils.js +20 -0
- package/library.js +49 -50
- package/package.json +1 -1
- package/plugin.json +13 -7
- package/public/admin.js +17 -20
package/lib/controllers.js
CHANGED
|
@@ -18,8 +18,10 @@ const sitemapLib = require('./sitemap');
|
|
|
18
18
|
const sources = require('./sources');
|
|
19
19
|
const { resolveLocalPath } = sources;
|
|
20
20
|
const staticExport = require('./static-export');
|
|
21
|
+
const {fixPrefixPath} = require("./utils");
|
|
21
22
|
|
|
22
23
|
const user = require.main.require('./src/user');
|
|
24
|
+
const winston = require.main.require('winston');
|
|
23
25
|
|
|
24
26
|
// Public controllers
|
|
25
27
|
|
|
@@ -35,22 +37,26 @@ const user = require.main.require('./src/user');
|
|
|
35
37
|
* @returns {Promise<void>}
|
|
36
38
|
*/
|
|
37
39
|
async function renderPage(req, res, next) {
|
|
38
|
-
// Strip /api prefix if present. ajaxify fetches /api/{path} for SPA
|
|
39
|
-
// navigation; the catch-all in library.js dispatches both forms here.
|
|
40
|
+
// Strip /api prefix if present. ajaxify fetches /api/{path} for SPA navigation
|
|
40
41
|
const urlPath = (req.path.startsWith('/api/')
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
42
|
+
? req.path.slice(4)
|
|
43
|
+
: req.path
|
|
44
|
+
)
|
|
44
45
|
|
|
46
|
+
// Grab the possible sources this route matches
|
|
45
47
|
const matchingSources = sources.getAll().filter(function (s) {
|
|
46
|
-
|
|
48
|
+
const urlPrefix = fixPrefixPath(s.urlPrefix);
|
|
49
|
+
return urlPath.startsWith(urlPrefix);
|
|
47
50
|
});
|
|
48
51
|
|
|
49
52
|
// Longest prefix wins (e.g. "wiki/guide" over "wiki") when both match.
|
|
50
|
-
matchingSources.sort(function (a, b) { return b.urlPrefix.length - a.urlPrefix.length; });
|
|
53
|
+
matchingSources.sort(function (a, b) { return fixPrefixPath(b.urlPrefix).length - fixPrefixPath(a.urlPrefix).length; });
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
const rawPath =
|
|
55
|
+
let prefix = matchingSources.length ? matchingSources[0].urlPrefix : '';
|
|
56
|
+
const rawPath = req.params[0] ? req.params[0] : '';
|
|
57
|
+
|
|
58
|
+
winston.verbose('[mdx-page-renderer] Matching prefix: ' + prefix);
|
|
59
|
+
winston.verbose('[mdx-page-renderer] Matching route: ' + rawPath);
|
|
54
60
|
|
|
55
61
|
// Treat a bare prefix URL as a request for index.mdx.
|
|
56
62
|
const effectivePath = rawPath || 'index';
|
|
@@ -70,19 +76,33 @@ async function renderPage(req, res, next) {
|
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
if (!filePath) {
|
|
79
|
+
winston.verbose('[mdx-page-renderer] Unable to find file path: ' + resolvedEffectivePath);
|
|
80
|
+
|
|
73
81
|
// No content found for this path. Prompt to admins visiting the bare prefix URL; everyone else gets a 404.
|
|
74
82
|
if (!rawPath) {
|
|
75
83
|
const isAdmin = req.uid && await user.isAdministrator(req.uid);
|
|
76
84
|
if (isAdmin) {
|
|
77
85
|
return res.render('mdx-page', {
|
|
78
86
|
title: 'MDX Page',
|
|
79
|
-
content: buildNoContentHtml(prefix),
|
|
87
|
+
content: buildNoContentHtml(fixPrefixPath(prefix)),
|
|
80
88
|
});
|
|
81
89
|
}
|
|
82
90
|
}
|
|
91
|
+
|
|
83
92
|
return next();
|
|
84
93
|
}
|
|
85
94
|
|
|
95
|
+
// Due to needing to handle relative paths, we need to invert any fixing of the prefix path in the same way here
|
|
96
|
+
if (prefix) {
|
|
97
|
+
if (prefix.charAt(0) === '/') {
|
|
98
|
+
prefix = prefix.substring(1, prefix.length);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (prefix.slice(-1) === '/') {
|
|
102
|
+
prefix = prefix.substring(0, prefix.length - 1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
86
106
|
try {
|
|
87
107
|
const sourceText = fs.readFileSync(filePath, 'utf8');
|
|
88
108
|
|
|
@@ -117,7 +137,7 @@ async function renderPage(req, res, next) {
|
|
|
117
137
|
|
|
118
138
|
res.render('mdx-page', { title, content: html, breadcrumbs, showSidebarToc, tocHtml });
|
|
119
139
|
} catch (err) {
|
|
120
|
-
|
|
140
|
+
winston.error('[mdx-page-renderer] Failed to render page ' + filePath + ':', err);
|
|
121
141
|
res.status(500).render('mdx-page', {
|
|
122
142
|
title: 'Render error',
|
|
123
143
|
content: '<p>Failed to render this page. Check the server logs for details.</p>' +
|
package/lib/sources.js
CHANGED
|
@@ -10,6 +10,28 @@
|
|
|
10
10
|
* flagged for admin review.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} SourceConfig
|
|
15
|
+
* @property {string} type
|
|
16
|
+
* @property {string} label
|
|
17
|
+
* @property {string} urlPrefix
|
|
18
|
+
* @property {string} url
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {Object} SourceObject
|
|
23
|
+
* @property {string} id
|
|
24
|
+
* @property {string} type
|
|
25
|
+
* @property {string} label
|
|
26
|
+
* @property {string} url
|
|
27
|
+
* @property {string} urlPrefix
|
|
28
|
+
* @property {string} localPath
|
|
29
|
+
* @property {string} createdAt
|
|
30
|
+
* @property {boolean} showIndexToc
|
|
31
|
+
* @property {string | undefined} asset
|
|
32
|
+
* @property {string | undefined} tag
|
|
33
|
+
*/
|
|
34
|
+
|
|
13
35
|
const crypto = require('crypto');
|
|
14
36
|
const fs = require('fs');
|
|
15
37
|
const https = require('https');
|
|
@@ -28,7 +50,8 @@ const settings = require('./settings');
|
|
|
28
50
|
/** Database key used to persist the list of configured sources. */
|
|
29
51
|
const DB_KEY = 'mdx-page-renderer:sources';
|
|
30
52
|
|
|
31
|
-
/** In-memory list of source objects. Populated by loadAll().
|
|
53
|
+
/** In-memory list of source objects. Populated by loadAll().
|
|
54
|
+
* @type {SourceObject[]} */
|
|
32
55
|
let sourceList = [];
|
|
33
56
|
|
|
34
57
|
// Public API
|
|
@@ -44,7 +67,7 @@ async function loadAll() {
|
|
|
44
67
|
|
|
45
68
|
/**
|
|
46
69
|
* getAll - returns a copy of the current source list.
|
|
47
|
-
* @returns {
|
|
70
|
+
* @returns {SourceObject[]}
|
|
48
71
|
*/
|
|
49
72
|
function getAll() {
|
|
50
73
|
return [...sourceList];
|
|
@@ -62,7 +85,7 @@ function getById(id) {
|
|
|
62
85
|
/**
|
|
63
86
|
* add - validates, creates, and persists a new source.
|
|
64
87
|
* Returns the created source object (with generated ID and localPath).
|
|
65
|
-
* @param {
|
|
88
|
+
* @param {SourceConfig} sourceConfig
|
|
66
89
|
* @returns {Promise<object>} The created source object.
|
|
67
90
|
*/
|
|
68
91
|
async function add(sourceConfig) {
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param prefix {string} A url prefix
|
|
3
|
+
* @returns {string} The prefix with a forward slash added to the front, and removed from the end
|
|
4
|
+
*/
|
|
5
|
+
const fixPrefixPath = (prefix) => {
|
|
6
|
+
if (prefix.charAt(0) !== '/') {
|
|
7
|
+
prefix = '/' + prefix;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Remove dangling slashes
|
|
11
|
+
if (prefix.slice(-1) === '/') {
|
|
12
|
+
prefix = prefix.substring(0, prefix.length - 1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return prefix;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
fixPrefixPath,
|
|
20
|
+
}
|
package/library.js
CHANGED
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const controllers = require('./lib/controllers');
|
|
9
|
-
const sources
|
|
10
|
-
const doxygen
|
|
11
|
-
const settings
|
|
9
|
+
const sources = require('./lib/sources');
|
|
10
|
+
const doxygen = require('./lib/doxygen');
|
|
11
|
+
const settings = require('./lib/settings');
|
|
12
|
+
const {fixPrefixPath} = require("./lib/utils");
|
|
13
|
+
const winston = require.main.require('winston');
|
|
12
14
|
|
|
13
15
|
// Provides setupAdminPageRoute which applies the admin middleware stack and
|
|
14
16
|
// auto-registers a /api/ JSON mirror of the route.
|
|
@@ -16,12 +18,14 @@ const routeHelpers = require.main.require('./src/routes/helpers');
|
|
|
16
18
|
|
|
17
19
|
const Plugin = module.exports;
|
|
18
20
|
|
|
21
|
+
const PLUGIN_NAME = 'mdx-page-renderer';
|
|
22
|
+
|
|
19
23
|
/**
|
|
20
24
|
* init - registered against the `static:app.load` hook.
|
|
21
25
|
* @param {{ router: import('express').Router, middleware: object }} params
|
|
22
26
|
* @returns {Promise<void>}
|
|
23
27
|
*/
|
|
24
|
-
Plugin.init = async function ({
|
|
28
|
+
Plugin.init = async function ({router, middleware}) {
|
|
25
29
|
await settings.load();
|
|
26
30
|
|
|
27
31
|
// Load content and Doxygen data from any previously-configured sources.
|
|
@@ -36,53 +40,48 @@ Plugin.init = async function ({ router, middleware }) {
|
|
|
36
40
|
// --- Admin panel page ---
|
|
37
41
|
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/mdx-page-renderer', controllers.renderAdmin);
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
router.post(`${base}/clear-cache`, controllers.clearRenderCache);
|
|
47
|
-
router.post(`${base}/export`, controllers.exportStatic);
|
|
48
|
-
|
|
49
|
-
// Inline source page editor endpoints
|
|
50
|
-
router.get(`${base}/inline/pages`, controllers.listInlinePages);
|
|
51
|
-
router.get(`${base}/inline/page`, controllers.getInlinePage);
|
|
52
|
-
router.post(`${base}/inline/page`, controllers.saveInlinePage);
|
|
53
|
-
router.delete(`${base}/inline/page`, controllers.deleteInlinePage);
|
|
54
|
-
|
|
55
|
-
// --- Content page catch-all ---
|
|
56
|
-
// One catch-all dispatches to the correct source at request time, so sources
|
|
57
|
-
// added in the admin panel take effect without a restart. Registered last so
|
|
58
|
-
// it does not shadow NodeBB's own routes.
|
|
59
|
-
router.get('*', function routeToDocPage(req, res, next) {
|
|
60
|
-
// ajaxify fetches /api/{path} for SPA navigation; strip it to get the real path.
|
|
61
|
-
const isApi = req.path.startsWith('/api/');
|
|
62
|
-
const urlPath = (isApi ? req.path.slice(4) : req.path).replace(/^\/+/, '');
|
|
63
|
-
|
|
64
|
-
if (!urlPath) {
|
|
65
|
-
return next();
|
|
43
|
+
const availableSources = sources.getAll();
|
|
44
|
+
// Sort the array so the most specific routes are setup first
|
|
45
|
+
availableSources.sort(function (a, b) { return b.urlPrefix.length - a.urlPrefix.length; })
|
|
46
|
+
for (const source of availableSources) {
|
|
47
|
+
let prefix = source.urlPrefix;
|
|
48
|
+
if (!prefix) {
|
|
49
|
+
continue;
|
|
66
50
|
}
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
const matched = sources.getAll().some(function (s) {
|
|
70
|
-
return urlPath === s.urlPrefix || urlPath.startsWith(s.urlPrefix + '/');
|
|
71
|
-
});
|
|
52
|
+
prefix = fixPrefixPath(prefix);
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
54
|
+
winston.info(`[mdx-page-renderer] Registering source: ${prefix}`);
|
|
55
|
+
routeHelpers.setupPageRoute(router, `${prefix}/*`, controllers.renderPage)
|
|
56
|
+
routeHelpers.setupPageRoute(router, `${prefix}`, controllers.renderPage)
|
|
57
|
+
}
|
|
58
|
+
};
|
|
76
59
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
60
|
+
Plugin.addRoutes = async ({router, middleware, helpers}) => {
|
|
61
|
+
const controllers = require('./lib/controllers');
|
|
62
|
+
const middlewares = [
|
|
63
|
+
middleware.authenticateRequest,
|
|
64
|
+
middleware.logApiUsage,
|
|
65
|
+
middleware.ensureLoggedIn,
|
|
66
|
+
middleware.admin.checkPrivileges,
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/save`, middlewares, controllers.saveSettings);
|
|
70
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/source`, middlewares, controllers.addSource);
|
|
71
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/source/update`, middlewares, controllers.updateSource);
|
|
72
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/source/remove`, middlewares, controllers.removeSource);
|
|
73
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/refresh`, middlewares, controllers.refreshSource);
|
|
74
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/clear-cache`, middlewares, controllers.clearRenderCache);
|
|
75
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/export`, middlewares, controllers.exportStatic);
|
|
76
|
+
|
|
77
|
+
// Inline source page editor endpoints
|
|
78
|
+
routeHelpers.setupApiRoute(router, 'get', `/${PLUGIN_NAME}/inline/pages`, middlewares, controllers.listInlinePages);
|
|
79
|
+
routeHelpers.setupApiRoute(router, 'get', `/${PLUGIN_NAME}/inline/page`, middlewares, controllers.getInlinePage);
|
|
80
|
+
routeHelpers.setupApiRoute(router, 'post', `/${PLUGIN_NAME}/inline/page`, middlewares, controllers.saveInlinePage);
|
|
81
|
+
routeHelpers.setupApiRoute(router, 'delete', `/${PLUGIN_NAME}/inline/page`, middlewares, controllers.deleteInlinePage);
|
|
82
|
+
|
|
83
|
+
routeHelpers.setupApiRoute(router, 'get', `/test`, (req, res) => {
|
|
84
|
+
helpers.formatApiResponse(200, res, {})
|
|
86
85
|
});
|
|
87
86
|
};
|
|
88
87
|
|
|
@@ -93,9 +92,9 @@ Plugin.init = async function ({ router, middleware }) {
|
|
|
93
92
|
*/
|
|
94
93
|
Plugin.addAdminNavigation = function (header) {
|
|
95
94
|
header.plugins.push({
|
|
96
|
-
route:
|
|
97
|
-
icon:
|
|
98
|
-
name:
|
|
95
|
+
route: '/plugins/mdx-page-renderer',
|
|
96
|
+
icon: 'fa-file-alt',
|
|
97
|
+
name: 'MDX Page Renderer',
|
|
99
98
|
});
|
|
100
99
|
|
|
101
100
|
return header;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@the-starport/nodebb-plugin-mdx-page-renderer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Serves MDX-based documentation pages within NodeBB, with server-side rendering and Doxygen API reference components.",
|
|
5
5
|
"main": "library.js",
|
|
6
6
|
"repository": {
|
package/plugin.json
CHANGED
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
"id": "nodebb-plugin-mdx-page-renderer",
|
|
3
3
|
"name": "MDX Page Renderer",
|
|
4
4
|
"description": "Serves MDX-based documentation pages within NodeBB with server-side rendering, Doxygen API reference components, and an admin panel for managing content sources.",
|
|
5
|
-
"version": "1.0.
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "https://codeberg.org/TheStarport/nodebb-plugin-mdx-page-renderer"
|
|
9
|
-
},
|
|
5
|
+
"version": "1.0.1",
|
|
10
6
|
"library": "./library.js",
|
|
11
7
|
"hooks": [
|
|
12
|
-
{
|
|
13
|
-
|
|
8
|
+
{
|
|
9
|
+
"hook": "static:app.load",
|
|
10
|
+
"method": "init"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"hook": "filter:admin.header.build",
|
|
14
|
+
"method": "addAdminNavigation"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"hook": "static:api.routes",
|
|
18
|
+
"method": "addRoutes"
|
|
19
|
+
}
|
|
14
20
|
],
|
|
15
21
|
"scss": [
|
|
16
22
|
"mdx.scss"
|
package/public/admin.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* Admin panel AMD module for the MDX Page Renderer plugin.
|
|
7
7
|
* Initial data comes from ajaxify.data (set by renderAdmin via res.render).
|
|
8
|
-
* Mutations POST to /
|
|
8
|
+
* Mutations POST to /api/v3/plugins/mdx-page-renderer/* with a CSRF token.
|
|
9
9
|
*/
|
|
10
10
|
define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alerts, bootbox) {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const API = config.relative_path + '/api/v3/plugins/mdx-page-renderer';
|
|
12
|
+
const NAV_API = config.relative_path + '/api/admin/plugins/mdx-page-renderer';
|
|
13
13
|
|
|
14
14
|
// HTTP helpers
|
|
15
15
|
function postJSON(url, body) {
|
|
@@ -22,11 +22,10 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
// Data loading
|
|
27
26
|
// Reload settings and sources from the /api/ mirror of the admin page route.
|
|
28
27
|
function loadData() {
|
|
29
|
-
$.get(
|
|
28
|
+
$.get(NAV_API)
|
|
30
29
|
.then(function (data) {
|
|
31
30
|
populateSettings(data.settings || {});
|
|
32
31
|
renderSourceList(data.sources || []);
|
|
@@ -109,7 +108,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
109
108
|
|
|
110
109
|
const pathsEl = document.getElementById('mdx-content-paths');
|
|
111
110
|
if (pathsEl) {
|
|
112
|
-
$.get(
|
|
111
|
+
$.get(NAV_API)
|
|
113
112
|
.then(function (data) {
|
|
114
113
|
const sources = data.sources || [];
|
|
115
114
|
pathsEl.innerHTML = sources.map(function (s) {
|
|
@@ -189,7 +188,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
189
188
|
var listEl = document.getElementById('mdx-inline-page-list');
|
|
190
189
|
listEl.innerHTML = '<p class="text-muted">Loading...</p>';
|
|
191
190
|
|
|
192
|
-
$.get(
|
|
191
|
+
$.get(API + '/inline/pages', { id: inlineEditor.sourceId })
|
|
193
192
|
.then(function (data) {
|
|
194
193
|
var pages = data.pages || [];
|
|
195
194
|
if (!pages.length) {
|
|
@@ -229,7 +228,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
229
228
|
inlineEditor.pagePath = pagePath;
|
|
230
229
|
document.getElementById('mdx-inline-path').value = pagePath;
|
|
231
230
|
|
|
232
|
-
$.get(
|
|
231
|
+
$.get(API + '/inline/page', { id: inlineEditor.sourceId, path: pagePath })
|
|
233
232
|
.then(function (data) {
|
|
234
233
|
document.getElementById('mdx-inline-textarea').value = data.content || '';
|
|
235
234
|
inlineEditor.showEditPane();
|
|
@@ -260,7 +259,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
260
259
|
|
|
261
260
|
resultEl.textContent = 'Saving...';
|
|
262
261
|
|
|
263
|
-
postJSON(
|
|
262
|
+
postJSON(API + '/inline/page', { id: inlineEditor.sourceId, path: pagePath, content: content })
|
|
264
263
|
.then(function () {
|
|
265
264
|
inlineEditor.pagePath = pagePath;
|
|
266
265
|
document.getElementById('mdx-inline-path').value = pagePath;
|
|
@@ -276,7 +275,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
276
275
|
if (!window.confirm('Delete ' + pagePath + '?')) return;
|
|
277
276
|
|
|
278
277
|
$.ajax({
|
|
279
|
-
url:
|
|
278
|
+
url: API + '/inline/page',
|
|
280
279
|
type: 'DELETE',
|
|
281
280
|
contentType: 'application/json',
|
|
282
281
|
data: JSON.stringify({ id: inlineEditor.sourceId, path: pagePath }),
|
|
@@ -385,7 +384,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
385
384
|
submitBtn.disabled = true;
|
|
386
385
|
submitBtn.textContent = 'Adding...';
|
|
387
386
|
|
|
388
|
-
postJSON(`${
|
|
387
|
+
postJSON(`${API}/source`, {type, label, urlPrefix, url, asset, tag})
|
|
389
388
|
.then(function (res) {
|
|
390
389
|
const sourceId = res.source.id;
|
|
391
390
|
const sourceLabel = res.source.label;
|
|
@@ -406,7 +405,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
406
405
|
'</div>';
|
|
407
406
|
submitBtn.textContent = 'Downloading...';
|
|
408
407
|
|
|
409
|
-
postJSON(`${
|
|
408
|
+
postJSON(`${API}/refresh`, {id: sourceId})
|
|
410
409
|
.then(function (refreshRes) {
|
|
411
410
|
const r = refreshRes.report;
|
|
412
411
|
hideAddForm();
|
|
@@ -433,7 +432,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
433
432
|
// Source operations
|
|
434
433
|
// Patch mutable source fields; reloads on failure to revert the UI.
|
|
435
434
|
function updateSource(id, data) {
|
|
436
|
-
postJSON(`${
|
|
435
|
+
postJSON(`${API}/source/update`, {id, ...data})
|
|
437
436
|
.catch(function (err) {
|
|
438
437
|
const msg = (err.responseJSON && err.responseJSON.error) || err.statusText;
|
|
439
438
|
alerts.error(`Failed to update source: ${msg}`);
|
|
@@ -446,7 +445,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
446
445
|
const resultEl = document.querySelector(`.mdx-refresh-result[data-id="${id}"]`);
|
|
447
446
|
if (resultEl) resultEl.textContent = 'Refreshing...';
|
|
448
447
|
|
|
449
|
-
postJSON(`${
|
|
448
|
+
postJSON(`${API}/refresh`, {id})
|
|
450
449
|
.then(function (res) {
|
|
451
450
|
const r = res.report;
|
|
452
451
|
let summary = `Added: ${r.added.length}, Updated: ${r.updated.length}, Deleted: ${r.autoDeleted.length}`;
|
|
@@ -471,7 +470,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
471
470
|
},
|
|
472
471
|
callback: function (confirmed) {
|
|
473
472
|
if (!confirmed) return;
|
|
474
|
-
postJSON(`${
|
|
473
|
+
postJSON(`${API}/source/remove`, {id})
|
|
475
474
|
.then(function () {
|
|
476
475
|
loadData();
|
|
477
476
|
})
|
|
@@ -493,7 +492,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
493
492
|
data[el.name] = el.value;
|
|
494
493
|
});
|
|
495
494
|
|
|
496
|
-
postJSON(`${
|
|
495
|
+
postJSON(`${API}/save`, data)
|
|
497
496
|
.then(function () {
|
|
498
497
|
alerts.success('Settings saved.');
|
|
499
498
|
})
|
|
@@ -507,7 +506,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
507
506
|
const resultEl = document.getElementById('mdx-clear-cache-result');
|
|
508
507
|
resultEl.textContent = 'Clearing...';
|
|
509
508
|
|
|
510
|
-
postJSON(`${
|
|
509
|
+
postJSON(`${API}/clear-cache`, {})
|
|
511
510
|
.then(function () {
|
|
512
511
|
resultEl.textContent = 'Cache cleared. Next page load will recompile.';
|
|
513
512
|
})
|
|
@@ -520,7 +519,7 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
520
519
|
const resultEl = document.getElementById('mdx-export-result');
|
|
521
520
|
resultEl.textContent = 'Building...';
|
|
522
521
|
|
|
523
|
-
postJSON(`${
|
|
522
|
+
postJSON(`${API}/export`, {})
|
|
524
523
|
.then(function (res) {
|
|
525
524
|
const r = res.result;
|
|
526
525
|
let msg = `Done. Built ${r.built} page(s).`;
|
|
@@ -569,8 +568,6 @@ define('admin/plugins/mdx-page-renderer', ['alerts', 'bootbox'], function (alert
|
|
|
569
568
|
// Delegate Refresh/Remove button clicks via the source list container.
|
|
570
569
|
document.getElementById('mdx-source-list').addEventListener('click', function (e) {
|
|
571
570
|
const id = e.target.dataset.id;
|
|
572
|
-
console.log(e.target);
|
|
573
|
-
console.log(id);
|
|
574
571
|
if (!id) {
|
|
575
572
|
return;
|
|
576
573
|
}
|