wiki-server 0.23.0 → 0.24.0
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/.github/workflows/node.js.yml +2 -2
- package/lib/page.coffee +21 -4
- package/lib/search.coffee +8 -25
- package/lib/server.coffee +4 -2
- package/package.json +5 -5
- package/test/sitemap.coffee +1 -0
|
@@ -16,11 +16,11 @@ jobs:
|
|
|
16
16
|
|
|
17
17
|
strategy:
|
|
18
18
|
matrix:
|
|
19
|
-
node-version: [
|
|
19
|
+
node-version: [18.x, 20.x, 21.x]
|
|
20
20
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
21
21
|
|
|
22
22
|
steps:
|
|
23
|
-
- uses: actions/checkout@
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
24
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
25
25
|
uses: actions/setup-node@v3
|
|
26
26
|
with:
|
package/lib/page.coffee
CHANGED
|
@@ -87,6 +87,25 @@ module.exports = exports = (argv) ->
|
|
|
87
87
|
# Reads and writes are async, but serially queued to avoid race conditions.
|
|
88
88
|
queue = []
|
|
89
89
|
|
|
90
|
+
tryDefaults = (file, cb) ->
|
|
91
|
+
lastDefault = (cb) ->
|
|
92
|
+
defloc = path.join(argv.root, 'default-data', 'pages', file)
|
|
93
|
+
fs.exists defloc, (exists) ->
|
|
94
|
+
if exists
|
|
95
|
+
cb(defloc)
|
|
96
|
+
else
|
|
97
|
+
cb(null)
|
|
98
|
+
if argv.defaults
|
|
99
|
+
defloc = path.join(argv.data, '..', argv.defaults, 'pages', file)
|
|
100
|
+
console.log 'firstDefault', defloc
|
|
101
|
+
fs.exists defloc, (exists) ->
|
|
102
|
+
if exists
|
|
103
|
+
cb(defloc)
|
|
104
|
+
else
|
|
105
|
+
lastDefault(cb)
|
|
106
|
+
else
|
|
107
|
+
lastDefault(cb)
|
|
108
|
+
|
|
90
109
|
# Main file io function, when called without page it reads,
|
|
91
110
|
# when called with page it writes.
|
|
92
111
|
fileio = (action, file, page, cb) ->
|
|
@@ -175,12 +194,10 @@ module.exports = exports = (argv) ->
|
|
|
175
194
|
if exists
|
|
176
195
|
load_parse(loc, cb, {plugin: undefined})
|
|
177
196
|
else
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if exists
|
|
197
|
+
tryDefaults(file, (defloc) ->
|
|
198
|
+
if defloc
|
|
181
199
|
load_parse(defloc, cb)
|
|
182
200
|
else
|
|
183
|
-
|
|
184
201
|
glob "wiki-plugin-*/pages", {cwd: argv.packageDir}, (e, plugins) ->
|
|
185
202
|
if e then return cb(e)
|
|
186
203
|
|
package/lib/search.coffee
CHANGED
|
@@ -46,9 +46,6 @@ module.exports = exports = (argv) ->
|
|
|
46
46
|
|
|
47
47
|
searchPageUpdate = (slug, page, cb) ->
|
|
48
48
|
# to update we have to remove the page first, and then readd it
|
|
49
|
-
timeLabel = "SITE INDEX update #{slug} - #{wikiName}"
|
|
50
|
-
console.time timeLabel
|
|
51
|
-
|
|
52
49
|
try
|
|
53
50
|
pageText = page.story.reduce( extractPageText, '')
|
|
54
51
|
catch err
|
|
@@ -66,37 +63,29 @@ module.exports = exports = (argv) ->
|
|
|
66
63
|
'title': page.title
|
|
67
64
|
'content': pageText
|
|
68
65
|
}
|
|
69
|
-
console.timeEnd timeLabel
|
|
70
66
|
cb()
|
|
71
67
|
|
|
72
68
|
searchPageRemove = (slug, cb) ->
|
|
73
69
|
# remove page from index
|
|
74
70
|
timeLabel = "SITE INDEX page remove #{slug} - #{wikiName}"
|
|
75
|
-
console.time timeLabel
|
|
76
71
|
try
|
|
77
72
|
siteIndex.discard slug
|
|
78
73
|
catch err
|
|
79
74
|
# swallow error, if the page was not in index
|
|
80
75
|
console.log "removing #{slug} from index #{wikiName} failed", err unless err.message.includes('not in the index')
|
|
81
|
-
console.timeEnd timeLabel
|
|
82
76
|
cb()
|
|
83
77
|
|
|
84
78
|
searchSave = (siteIndex, cb) ->
|
|
85
79
|
# save index to file
|
|
86
|
-
timeLabel = "SITE INDEX #{wikiName} : Saved"
|
|
87
|
-
console.time timeLabel
|
|
88
|
-
|
|
89
80
|
fs.exists argv.status, (exists) ->
|
|
90
81
|
if exists
|
|
91
82
|
writeFileAtomic siteIndexLoc, JSON.stringify(siteIndex), (e) ->
|
|
92
|
-
console.timeEnd timeLabel
|
|
93
83
|
return cb(e) if e
|
|
94
84
|
touch indexUpdateFlag, (err) ->
|
|
95
85
|
cb()
|
|
96
86
|
else
|
|
97
87
|
mkdirp argv.status, ->
|
|
98
88
|
writeFileAtomic siteIndexLoc, JSON.stringify(siteIndex), (e) ->
|
|
99
|
-
console.timeEnd timeLabel
|
|
100
89
|
return cb(e) if e
|
|
101
90
|
touch indexUpdateFlag, (err) ->
|
|
102
91
|
cb()
|
|
@@ -104,8 +93,6 @@ module.exports = exports = (argv) ->
|
|
|
104
93
|
|
|
105
94
|
searchRestore = (cb) ->
|
|
106
95
|
# restore index, or create if it doesn't already exist
|
|
107
|
-
timeLabel = "SITE INDEX #{wikiName} : Restored"
|
|
108
|
-
console.time timeLabel
|
|
109
96
|
fs.exists siteIndexLoc, (exists) ->
|
|
110
97
|
if exists
|
|
111
98
|
fs.readFile(siteIndexLoc, (err, data) ->
|
|
@@ -115,7 +102,6 @@ module.exports = exports = (argv) ->
|
|
|
115
102
|
fields: ['title', 'content']
|
|
116
103
|
catch e
|
|
117
104
|
return cb(e)
|
|
118
|
-
console.timeEnd timeLabel
|
|
119
105
|
process.nextTick( ->
|
|
120
106
|
serial(queue.shift())))
|
|
121
107
|
|
|
@@ -150,19 +136,16 @@ module.exports = exports = (argv) ->
|
|
|
150
136
|
try
|
|
151
137
|
if currentItem.text?
|
|
152
138
|
switch currentItem.type
|
|
153
|
-
when 'paragraph'
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
pageText += ' ' + currentItem.text.replace /\[{2}|\[(?:[\S]+)|\]{1,2}|\\n/g, ' '
|
|
158
|
-
when 'html'
|
|
159
|
-
pageText += ' ' + currentItem.text.replace /<[^\>]*>?/g, ''
|
|
139
|
+
when 'paragraph', 'markdown', 'html', 'reference'
|
|
140
|
+
noLinks = currentItem.text.replace /\[{2}|\[(?:[\S]+)|\]{1,2}/g, ''
|
|
141
|
+
# strip out all tags.
|
|
142
|
+
pageText += noLinks.replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, ' ')
|
|
160
143
|
else
|
|
161
144
|
if currentItem.text?
|
|
162
145
|
for line in currentItem.text.split /\r\n?|\n/
|
|
163
146
|
pageText += ' ' + line.replace /\[{2}|\[(?:[\S]+)|\]{1,2}/g, '' unless line.match /^[A-Z]+[ ].*/
|
|
164
147
|
catch err
|
|
165
|
-
throw new Error("Error extracting text from #{currentIndex}, #{err}")
|
|
148
|
+
throw new Error("Error extracting text from #{currentIndex}, #{err}, #{err.stack}")
|
|
166
149
|
pageText
|
|
167
150
|
|
|
168
151
|
|
|
@@ -192,8 +175,8 @@ module.exports = exports = (argv) ->
|
|
|
192
175
|
# we save the pagehandler, so we can recreate the site index if it is removed
|
|
193
176
|
searchPageHandler = pagehandler if !searchPageHandler?
|
|
194
177
|
|
|
195
|
-
timeLabel = "SITE INDEX #{wikiName} : Created"
|
|
196
|
-
console.time timeLabel
|
|
178
|
+
#timeLabel = "SITE INDEX #{wikiName} : Created"
|
|
179
|
+
#console.time timeLabel
|
|
197
180
|
|
|
198
181
|
pagehandler.slugs (e, slugs) ->
|
|
199
182
|
if e
|
|
@@ -227,7 +210,7 @@ module.exports = exports = (argv) ->
|
|
|
227
210
|
|
|
228
211
|
Promise.all(indexPromises)
|
|
229
212
|
.then () ->
|
|
230
|
-
console.timeEnd timeLabel
|
|
213
|
+
# console.timeEnd timeLabel
|
|
231
214
|
process.nextTick ( ->
|
|
232
215
|
serial(queue.shift()))
|
|
233
216
|
|
package/lib/server.coffee
CHANGED
|
@@ -33,7 +33,9 @@ glob = require 'glob'
|
|
|
33
33
|
async = require 'async'
|
|
34
34
|
f = require('flates')
|
|
35
35
|
sanitize = require '@mapbox/sanitize-caja'
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
# node-fetch is now ESM only
|
|
38
|
+
fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
|
37
39
|
|
|
38
40
|
# Express 4 middleware
|
|
39
41
|
logger = require 'morgan'
|
|
@@ -145,7 +147,7 @@ module.exports = exports = (argv) ->
|
|
|
145
147
|
# assume http, as we know no better at this point and we need to specify a protocol.
|
|
146
148
|
remoteURL = new URL("http://#{remote}/#{slug}.json").toString()
|
|
147
149
|
# set a two second timeout
|
|
148
|
-
fetch(remoteURL, {
|
|
150
|
+
fetch(remoteURL, {signal: AbortSignal.timeout(2000)})
|
|
149
151
|
.then (res) ->
|
|
150
152
|
if res.ok
|
|
151
153
|
return res
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wiki-server",
|
|
3
3
|
"description": "A Federated Wiki Server",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.24.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ward Cunningham",
|
|
7
7
|
"email": "ward@c2.com",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"cookie-parser": "^1.4.4",
|
|
29
29
|
"errorhandler": "^1.5.1",
|
|
30
30
|
"express": "^4.17.1",
|
|
31
|
-
"express-hbs": "^2.
|
|
31
|
+
"express-hbs": "^2.5.0",
|
|
32
32
|
"flates": "0.0.5",
|
|
33
33
|
"glob": "^7.2.3",
|
|
34
34
|
"lodash": "^4.17.19",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"minisearch": "^6.0.1",
|
|
37
37
|
"mkdirp": "^0.5.6",
|
|
38
38
|
"morgan": "^1.9.1",
|
|
39
|
-
"node-fetch": "^
|
|
39
|
+
"node-fetch": "^3.3.2",
|
|
40
40
|
"write-file-atomic": "^5.0.0",
|
|
41
41
|
"xml2js": "^0.5.0"
|
|
42
42
|
},
|
|
@@ -51,12 +51,12 @@
|
|
|
51
51
|
"mocha": "^10.2.0",
|
|
52
52
|
"should": "^13.2.3",
|
|
53
53
|
"supertest": "^6.3.3",
|
|
54
|
-
"wiki-client": "^0.
|
|
54
|
+
"wiki-client": "^0.29.0",
|
|
55
55
|
"wiki-plugin-activity": "^0.5.0",
|
|
56
56
|
"wiki-plugin-video": "^0.3.0"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
|
-
"node": ">=
|
|
59
|
+
"node": ">=18.x"
|
|
60
60
|
},
|
|
61
61
|
"testling": {
|
|
62
62
|
"harness": "mocha"
|
package/test/sitemap.coffee
CHANGED
|
@@ -19,6 +19,7 @@ describe 'sitemap', ->
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
request = request('http://localhost:55556')
|
|
22
|
+
fs.mkdirSync path.join('/tmp', 'sfwtests', testid, 'pages'), {recursive: true}
|
|
22
23
|
|
|
23
24
|
# location of the sitemap
|
|
24
25
|
sitemapLoc = path.join('/tmp', 'sfwtests', testid, 'status', 'sitemap.json')
|