ep_markdown 12.0.6 → 12.0.8
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/exportMarkdown.ts +19 -1
- package/express.ts +26 -0
- package/package.json +5 -2
package/exportMarkdown.ts
CHANGED
|
@@ -6,6 +6,10 @@ import {StringIterator} from 'ep_etherpad-lite/static/js/StringIterator'
|
|
|
6
6
|
import {StringAssembler} from 'ep_etherpad-lite/static/js/StringAssembler'
|
|
7
7
|
|
|
8
8
|
const padManager = require('ep_etherpad-lite/node/db/PadManager');
|
|
9
|
+
// ReadOnlyManager uses `export default {...}` (ESM-style), so when loaded
|
|
10
|
+
// via CommonJS `require` the API lives under `.default`. Unwrap explicitly
|
|
11
|
+
// so `readOnlyManager.isReadOnlyId` resolves.
|
|
12
|
+
const readOnlyManager = require('ep_etherpad-lite/node/db/ReadOnlyManager').default;
|
|
9
13
|
|
|
10
14
|
const getMarkdownFromAtext = (pad, atext) => {
|
|
11
15
|
const apool = pad.apool();
|
|
@@ -344,8 +348,22 @@ const getPadMarkdown = async (pad, revNum) => {
|
|
|
344
348
|
return getMarkdownFromAtext(pad, atext);
|
|
345
349
|
};
|
|
346
350
|
|
|
351
|
+
// Readonly pad IDs (`r.*`) must be resolved to their underlying pad ID
|
|
352
|
+
// before loading — otherwise padManager.getPad creates an empty pad under
|
|
353
|
+
// the readonly ID and the export returns nothing. Matches the behavior of
|
|
354
|
+
// Etherpad core's /export/:type handler (see importexport.ts).
|
|
355
|
+
const resolvePadId = async (padId) => {
|
|
356
|
+
if (readOnlyManager.isReadOnlyId(padId)) {
|
|
357
|
+
return await readOnlyManager.getPadId(padId);
|
|
358
|
+
}
|
|
359
|
+
return padId;
|
|
360
|
+
};
|
|
361
|
+
|
|
347
362
|
exports.getPadMarkdownDocument =
|
|
348
|
-
async (padId, revNum) =>
|
|
363
|
+
async (padId, revNum) => {
|
|
364
|
+
const resolvedId = await resolvePadId(padId);
|
|
365
|
+
return await getPadMarkdown(await padManager.getPad(resolvedId), revNum);
|
|
366
|
+
};
|
|
349
367
|
|
|
350
368
|
// copied from ACE
|
|
351
369
|
const _REGEX_WORDCHAR = new RegExp([
|
package/express.ts
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const exportMarkdown = require('./exportMarkdown');
|
|
4
|
+
const settings = require('ep_etherpad-lite/node/utils/Settings');
|
|
5
|
+
const rateLimit = require('express-rate-limit');
|
|
6
|
+
|
|
7
|
+
// Mirrors the rate limiting, CORS header, and readonly-pad handling that
|
|
8
|
+
// Etherpad core applies to its native /p/:pad/export/:type routes
|
|
9
|
+
// (src/node/hooks/express/importexport.ts). Without these, integrators hit
|
|
10
|
+
// browser CORS errors on repeated fetches (issue #139) and the readonly
|
|
11
|
+
// `r.*` pad IDs fail because markdown's export path did not resolve them
|
|
12
|
+
// to their underlying pad IDs.
|
|
4
13
|
|
|
5
14
|
exports.expressCreateServer = (hookName, {app}) => {
|
|
15
|
+
const limiter = rateLimit({
|
|
16
|
+
...settings.importExportRateLimiting,
|
|
17
|
+
handler: (request: any) => {
|
|
18
|
+
if (request.rateLimit.current === request.rateLimit.limit + 1) {
|
|
19
|
+
console.warn('Import/Export rate limiter triggered on ' +
|
|
20
|
+
`"${request.originalUrl}" for IP address ${request.ip}`);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Apply the core rate limiter to both with-revision and without-revision
|
|
26
|
+
// markdown export endpoints, matching the pattern used by Etherpad core.
|
|
27
|
+
app.use('/p/:padId/export/markdown', limiter);
|
|
28
|
+
app.use('/p/:padId/:revNum/export/markdown', limiter);
|
|
29
|
+
|
|
6
30
|
app.get('/p/:padId/export/markdown', async (req: any, res: any, next: any) => {
|
|
7
31
|
try {
|
|
8
32
|
const {padId} = req.params;
|
|
33
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
9
34
|
res.attachment(`${padId}.md`);
|
|
10
35
|
res.contentType('plain/text');
|
|
11
36
|
res.send(await exportMarkdown.getPadMarkdownDocument(padId));
|
|
@@ -17,6 +42,7 @@ exports.expressCreateServer = (hookName, {app}) => {
|
|
|
17
42
|
app.get('/p/:padId/:revNum/export/markdown', async (req: any, res: any, next: any) => {
|
|
18
43
|
try {
|
|
19
44
|
const {padId, revNum} = req.params;
|
|
45
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
20
46
|
res.attachment(`${padId}.md`);
|
|
21
47
|
res.contentType('plain/text');
|
|
22
48
|
res.send(await exportMarkdown.getPadMarkdownDocument(padId, revNum));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ep_markdown",
|
|
3
3
|
"description": "Edit and Export as Markdown in Etherpad",
|
|
4
|
-
"version": "12.0.
|
|
4
|
+
"version": "12.0.8",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "John McLear",
|
|
7
7
|
"email": "john@mclear.co.uk",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/mocha": "^10.0.10",
|
|
26
|
-
"@types/node": "^25.
|
|
26
|
+
"@types/node": "^25.8.0",
|
|
27
27
|
"eslint": "^8.57.1",
|
|
28
28
|
"eslint-config-etherpad": "^4.0.5",
|
|
29
29
|
"typescript": "^6.0.3"
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
"engines": {
|
|
36
36
|
"node": ">=18.0.0"
|
|
37
37
|
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"express-rate-limit": "^8.0.0 || ^7.0.0"
|
|
40
|
+
},
|
|
38
41
|
"peerDependenciesMeta": {
|
|
39
42
|
"ep_headings2": {
|
|
40
43
|
"optional": true
|