larvitcms 2.0.0 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc +85 -87
- package/.github/workflows/ci.yml +14 -0
- package/README.md +2 -0
- package/cms.js +82 -181
- package/dataWriter.js +60 -312
- package/dbmigration/5.js +11 -21
- package/package.json +14 -19
- package/renovate.json +2 -7
- package/test/00test.js +135 -221
- package/.travis.yml +0 -36
- package/test/98lint.js +0 -9
- package/test/99close.js +0 -7
package/.eslintrc
CHANGED
@@ -1,88 +1,86 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
}
|
88
|
-
}
|
2
|
+
"root": true,
|
3
|
+
"parserOptions": {
|
4
|
+
"ecmaVersion": 2020
|
5
|
+
},
|
6
|
+
"env": {
|
7
|
+
"es6": true,
|
8
|
+
"mocha": true,
|
9
|
+
"node": true
|
10
|
+
},
|
11
|
+
"rules": {
|
12
|
+
"array-bracket-newline": ["error", "consistent"],
|
13
|
+
"array-bracket-spacing": ["error", "never"],
|
14
|
+
"block-spacing": ["error", "always"],
|
15
|
+
"brace-style": ["error", "1tbs", {"allowSingleLine": true}],
|
16
|
+
"comma-dangle": ["error", "always-multiline"],
|
17
|
+
"comma-spacing": ["error", {"before": false, "after": true}],
|
18
|
+
"comma-style": ["error", "last"],
|
19
|
+
"computed-property-spacing": ["error", "never"],
|
20
|
+
"consistent-this": ["error", "that"],
|
21
|
+
"eol-last": ["error", "always"],
|
22
|
+
"eqeqeq": ["warn", "always"],
|
23
|
+
"func-call-spacing": ["error", "never"],
|
24
|
+
"func-style": ["error", "declaration", {"allowArrowFunctions": true}],
|
25
|
+
"function-paren-newline": ["error", "multiline"],
|
26
|
+
"indent": ["error", "tab"],
|
27
|
+
"key-spacing": [
|
28
|
+
"error",
|
29
|
+
{"beforeColon": false, "afterColon": true, "mode": "strict"}
|
30
|
+
],
|
31
|
+
"keyword-spacing": ["error", {"before": true, "after": true}],
|
32
|
+
"linebreak-style": ["error", "unix"],
|
33
|
+
"lines-around-comment": ["error", {"beforeBlockComment": true, "afterBlockComment": false}],
|
34
|
+
"lines-between-class-members": ["error", "always"],
|
35
|
+
"new-cap": ["error"],
|
36
|
+
"new-parens": ["error"],
|
37
|
+
"no-dupe-args": ["error"],
|
38
|
+
"no-dupe-keys": ["error"],
|
39
|
+
"no-invalid-regexp": ["error"],
|
40
|
+
"no-irregular-whitespace": ["error", {"skipStrings": true, "skipComments": true, "skipRegExps": true, "skipTemplates": true}],
|
41
|
+
"no-lonely-if": ["error"],
|
42
|
+
"no-mixed-operators": ["error"],
|
43
|
+
"no-mixed-requires": ["off"],
|
44
|
+
"no-mixed-spaces-and-tabs": ["error"],
|
45
|
+
"no-multi-spaces": ["error", { "ignoreEOLComments": false }],
|
46
|
+
"no-multiple-empty-lines": ["error", {"max": 2, "maxEOF": 1, "maxBOF": 0}],
|
47
|
+
"no-process-exit": ["off"],
|
48
|
+
"no-redeclare": ["error"],
|
49
|
+
"no-sequences": ["error"],
|
50
|
+
"no-shadow": ["off"],
|
51
|
+
"no-tabs": ["error", { "allowIndentationTabs": true }],
|
52
|
+
"no-trailing-spaces": ["error", {"ignoreComments": true}],
|
53
|
+
"no-underscore-dangle": ["off"],
|
54
|
+
"no-unexpected-multiline": ["error"],
|
55
|
+
"no-unreachable": ["error"],
|
56
|
+
"no-unused-expressions": ["error"],
|
57
|
+
"no-unused-vars": ["error", {"caughtErrors": "all"}],
|
58
|
+
"no-use-before-define": ["error", {"functions": true, "classes": true, "variables": true}],
|
59
|
+
"no-var": ["error"],
|
60
|
+
"no-whitespace-before-property": ["error"],
|
61
|
+
"nonblock-statement-body-position": ["error", "beside"],
|
62
|
+
"one-var": ["error", "never"],
|
63
|
+
"padding-line-between-statements": [
|
64
|
+
"error",
|
65
|
+
{"blankLine": "always", "prev": "*", "next": "return"},
|
66
|
+
{"blankLine": "any", "prev": ["const", "let"], "next": "*"}
|
67
|
+
],
|
68
|
+
"quote-props": ["error", "as-needed"],
|
69
|
+
"quotes": ["error", "single"],
|
70
|
+
"semi-spacing": ["error", {"before": false, "after": true}],
|
71
|
+
"semi-style": ["error", "last"],
|
72
|
+
"semi": ["error", "always"],
|
73
|
+
"space-before-blocks": ["error", "always"],
|
74
|
+
"space-before-function-paren": ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}],
|
75
|
+
"space-in-parens": ["error", "never"],
|
76
|
+
"space-infix-ops": ["error"],
|
77
|
+
"space-unary-ops": ["error", {"words": true, "nonwords": false}],
|
78
|
+
"spaced-comment": ["error", "always"],
|
79
|
+
"strict": ["error", "global"],
|
80
|
+
"template-tag-spacing": ["error", "never"],
|
81
|
+
"unicode-bom": ["error", "never"],
|
82
|
+
"valid-jsdoc": ["error", {"requireReturn": false}],
|
83
|
+
"valid-typeof": ["error"],
|
84
|
+
"vars-on-top": ["off"]
|
85
|
+
}
|
86
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
name: larvitcms CI
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
uses: larvit/standards/.github/workflows/test-mariadb.yml@master
|
8
|
+
|
9
|
+
publish:
|
10
|
+
if: github.ref == 'refs/heads/master'
|
11
|
+
needs: test
|
12
|
+
uses: larvit/standards/.github/workflows/publish.yml@master
|
13
|
+
secrets:
|
14
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
package/cms.js
CHANGED
@@ -1,25 +1,21 @@
|
|
1
1
|
/* eslint-disable no-tabs */
|
2
2
|
'use strict';
|
3
3
|
|
4
|
-
const topLogPrefix = 'larvitcms: ./cms.js: ';
|
5
|
-
const Intercom = require('larvitamintercom');
|
6
4
|
const DataWriter = require(__dirname + '/dataWriter.js');
|
7
|
-
const
|
5
|
+
const { Utils, Log } = require('larvitutils');
|
6
|
+
|
7
|
+
const topLogPrefix = 'larvitcms: ./cms.js: ';
|
8
8
|
|
9
9
|
class Cms {
|
10
10
|
constructor(options) {
|
11
|
-
const logPrefix = topLogPrefix + 'constructor() - ';
|
12
|
-
|
13
11
|
this.options = options || {};
|
14
12
|
|
15
13
|
if (!options.db) throw new Error('Missing required option "db"');
|
16
14
|
|
17
|
-
if (!options.lUtils) options.lUtils = new
|
15
|
+
if (!options.lUtils) options.lUtils = new Utils();
|
18
16
|
|
19
17
|
if (!this.options.log) {
|
20
|
-
|
21
|
-
|
22
|
-
this.options.log = new lUtils.Log();
|
18
|
+
this.options.log = new Log();
|
23
19
|
}
|
24
20
|
|
25
21
|
this.log = this.options.log;
|
@@ -28,44 +24,17 @@ class Cms {
|
|
28
24
|
this[key] = this.options[key];
|
29
25
|
}
|
30
26
|
|
31
|
-
if (!this.exchangeName) {
|
32
|
-
this.exchangeName = 'larvitcms';
|
33
|
-
}
|
34
|
-
|
35
|
-
if (!this.mode) {
|
36
|
-
this.log.info(logPrefix + 'No "mode" option given, defaulting to "noSync"');
|
37
|
-
this.mode = 'noSync';
|
38
|
-
} else if (['noSync', 'master', 'slave'].indexOf(this.mode) === -1) {
|
39
|
-
const err = new Error('Invalid "mode" option given: "' + this.mode + '"');
|
40
|
-
|
41
|
-
this.log.error(logPrefix + err.message);
|
42
|
-
throw err;
|
43
|
-
}
|
44
|
-
|
45
|
-
if (!this.intercom) {
|
46
|
-
this.log.info(logPrefix + 'No "intercom" option given, defaulting to "loopback interface"');
|
47
|
-
this.intercom = new Intercom('loopback interface');
|
48
|
-
}
|
49
|
-
|
50
27
|
this.dataWriter = new DataWriter({
|
51
|
-
exchangeName: this.exchangeName,
|
52
|
-
intercom: this.intercom,
|
53
|
-
mode: this.mode,
|
54
28
|
log: this.log,
|
55
29
|
db: this.db,
|
56
|
-
amsync_host: this.options.amsync_host || null,
|
57
|
-
amsync_minPort: this.options.amsync_minPort || null,
|
58
|
-
amsync_maxPort: this.options.amsync_maxPort || null
|
59
|
-
}, err => {
|
60
|
-
if (err) this.log.error(logPrefix + 'Failed to initialize dataWriter:' + err.message);
|
61
30
|
});
|
62
31
|
};
|
63
32
|
|
64
|
-
|
65
|
-
this.dataWriter.
|
33
|
+
async runDbMigrations() {
|
34
|
+
await this.dataWriter.runDbMigrations();
|
66
35
|
}
|
67
36
|
|
68
|
-
getPages(options
|
37
|
+
async getPages(options) {
|
69
38
|
const logPrefix = topLogPrefix + 'getPages() - ';
|
70
39
|
const tmpPages = {};
|
71
40
|
const dbFields = [];
|
@@ -73,10 +42,7 @@ class Cms {
|
|
73
42
|
|
74
43
|
let sql;
|
75
44
|
|
76
|
-
|
77
|
-
cb = options;
|
78
|
-
options = {};
|
79
|
-
}
|
45
|
+
options = options || {};
|
80
46
|
|
81
47
|
this.log.debug(logPrefix + 'Called with options: "' + JSON.stringify(options) + '"');
|
82
48
|
|
@@ -142,10 +108,8 @@ class Cms {
|
|
142
108
|
|
143
109
|
if (buffer === false) {
|
144
110
|
const e = new Error('Invalid page uuid supplied');
|
145
|
-
|
146
111
|
log.warn(logPrefix + e.message);
|
147
|
-
|
148
|
-
return cb(e);
|
112
|
+
throw e;
|
149
113
|
}
|
150
114
|
|
151
115
|
sql += '?,';
|
@@ -171,175 +135,112 @@ class Cms {
|
|
171
135
|
}
|
172
136
|
}
|
173
137
|
|
174
|
-
this.db.query(sql, dbFields
|
175
|
-
|
176
|
-
|
177
|
-
for (let i = 0; rows[i] !== undefined; i++) {
|
178
|
-
const uuid = this.lUtils.formatUuid(rows[i].uuid);
|
138
|
+
const { rows } = await this.db.query(sql, dbFields);
|
139
|
+
for (let i = 0; rows[i] !== undefined; i++) {
|
140
|
+
const uuid = this.lUtils.formatUuid(rows[i].uuid);
|
179
141
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
};
|
188
|
-
}
|
189
|
-
|
190
|
-
tmpPages[uuid].langs[rows[i].lang] = {
|
191
|
-
htmlTitle: rows[i].htmlTitle,
|
192
|
-
body1: rows[i].body1,
|
193
|
-
body2: rows[i].body2,
|
194
|
-
body3: rows[i].body3,
|
195
|
-
body4: rows[i].body4,
|
196
|
-
body5: rows[i].body5,
|
197
|
-
slug: rows[i].slug
|
142
|
+
if (tmpPages[uuid] === undefined) {
|
143
|
+
tmpPages[uuid] = {
|
144
|
+
uuid: uuid,
|
145
|
+
name: rows[i].name,
|
146
|
+
published: Boolean(rows[i].published),
|
147
|
+
template: rows[i].template,
|
148
|
+
langs: {},
|
198
149
|
};
|
199
150
|
}
|
200
151
|
|
201
|
-
|
202
|
-
|
203
|
-
|
152
|
+
tmpPages[uuid].langs[rows[i].lang] = {
|
153
|
+
htmlTitle: rows[i].htmlTitle,
|
154
|
+
body1: rows[i].body1,
|
155
|
+
body2: rows[i].body2,
|
156
|
+
body3: rows[i].body3,
|
157
|
+
body4: rows[i].body4,
|
158
|
+
body5: rows[i].body5,
|
159
|
+
slug: rows[i].slug,
|
160
|
+
};
|
161
|
+
}
|
204
162
|
|
205
|
-
|
206
|
-
|
163
|
+
for (const pageUuid in tmpPages) {
|
164
|
+
pages.push(tmpPages[pageUuid]);
|
165
|
+
}
|
166
|
+
|
167
|
+
return pages;
|
207
168
|
};
|
208
169
|
|
209
|
-
getSnippets(options
|
210
|
-
|
211
|
-
const dbFields = [];
|
212
|
-
let sql;
|
170
|
+
async getSnippets(options) {
|
171
|
+
options = options || {};
|
213
172
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
173
|
+
if (options.onlyNames) {
|
174
|
+
const { rows } = await this.db.query('SELECT DISTINCT name FROM cms_snippets ORDER BY name;');
|
175
|
+
return rows;
|
176
|
+
}
|
218
177
|
|
219
|
-
|
220
|
-
|
221
|
-
|
178
|
+
const dbFields = [];
|
179
|
+
let sql = 'SELECT * FROM cms_snippets\n';
|
180
|
+
sql += 'WHERE 1 + 1\n';
|
222
181
|
|
223
|
-
|
182
|
+
if (options.names !== undefined) {
|
183
|
+
if (typeof options.names === 'string') {
|
184
|
+
options.names = [options.names];
|
224
185
|
}
|
225
186
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
if (options.names !== undefined) {
|
230
|
-
if (typeof options.names === 'string') {
|
231
|
-
options.names = [options.names];
|
232
|
-
}
|
233
|
-
|
234
|
-
if (options.names.length === 0) {
|
235
|
-
options.names = [''];
|
236
|
-
}
|
237
|
-
|
238
|
-
sql += ' AND name IN (';
|
239
|
-
|
240
|
-
for (let i = 0; options.names[i] !== undefined; i++) {
|
241
|
-
sql += '?,';
|
242
|
-
dbFields.push(options.names[i]);
|
243
|
-
}
|
244
|
-
|
245
|
-
sql = sql.substring(0, sql.length - 1) + ')\n';
|
187
|
+
if (options.names.length === 0) {
|
188
|
+
options.names = [''];
|
246
189
|
}
|
247
190
|
|
248
|
-
sql += '
|
249
|
-
|
250
|
-
this.db.query(sql, dbFields, (err, rows) => {
|
251
|
-
const snippets = [];
|
191
|
+
sql += ' AND name IN (';
|
252
192
|
|
253
|
-
|
254
|
-
|
193
|
+
for (let i = 0; options.names[i] !== undefined; i++) {
|
194
|
+
sql += '?,';
|
195
|
+
dbFields.push(options.names[i]);
|
196
|
+
}
|
255
197
|
|
256
|
-
|
198
|
+
sql = sql.substring(0, sql.length - 1) + ')\n';
|
199
|
+
}
|
257
200
|
|
258
|
-
|
259
|
-
if (prevName !== rows[i].name) {
|
260
|
-
if (snippet) {
|
261
|
-
snippets.push(snippet);
|
262
|
-
}
|
201
|
+
sql += 'ORDER BY name, lang';
|
263
202
|
|
264
|
-
|
265
|
-
|
203
|
+
const { rows } = await this.db.query(sql, dbFields);
|
204
|
+
const snippets = [];
|
266
205
|
|
267
|
-
|
268
|
-
|
269
|
-
}
|
206
|
+
let snippet;
|
207
|
+
let prevName;
|
270
208
|
|
271
|
-
|
209
|
+
for (let i = 0; rows[i] !== undefined; i++) {
|
210
|
+
if (prevName !== rows[i].name) {
|
272
211
|
if (snippet) {
|
273
212
|
snippets.push(snippet);
|
274
213
|
}
|
275
214
|
|
276
|
-
|
277
|
-
}
|
278
|
-
});
|
279
|
-
}
|
280
|
-
|
281
|
-
rmPage(uuid, cb) {
|
282
|
-
const options = {exchange: this.exchangeName};
|
283
|
-
const message = {};
|
284
|
-
|
285
|
-
message.action = 'rmPage';
|
286
|
-
message.params = {};
|
215
|
+
snippet = {name: rows[i].name, langs: {}};
|
216
|
+
}
|
287
217
|
|
288
|
-
|
218
|
+
prevName = rows[i].name;
|
219
|
+
snippet.langs[rows[i].lang] = rows[i].body;
|
220
|
+
}
|
289
221
|
|
290
|
-
|
291
|
-
|
222
|
+
// Add the last one
|
223
|
+
if (snippet) {
|
224
|
+
snippets.push(snippet);
|
225
|
+
}
|
292
226
|
|
293
|
-
|
294
|
-
});
|
227
|
+
return snippets;
|
295
228
|
}
|
296
229
|
|
297
|
-
|
298
|
-
|
299
|
-
const message = {};
|
300
|
-
|
301
|
-
message.action = 'rmSnippet';
|
302
|
-
message.params = {};
|
303
|
-
|
304
|
-
message.params.data = {name: name};
|
305
|
-
|
306
|
-
this.dataWriter.intercom.send(message, options, (err, msgUuid) => {
|
307
|
-
if (err) return cb(err);
|
308
|
-
|
309
|
-
DataWriter.emitter.once(msgUuid, cb);
|
310
|
-
});
|
230
|
+
async rmPage(uuid) {
|
231
|
+
await this.dataWriter.rmPage(uuid);
|
311
232
|
}
|
312
233
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
message.action = 'savePage';
|
318
|
-
message.params = {};
|
319
|
-
|
320
|
-
message.params.data = data;
|
321
|
-
|
322
|
-
this.dataWriter.intercom.send(message, options, (err, msgUuid) => {
|
323
|
-
if (err) return cb(err);
|
234
|
+
async rmSnippet(name) {
|
235
|
+
await this.dataWriter.rmSnippet(name);
|
236
|
+
}
|
324
237
|
|
325
|
-
|
326
|
-
|
238
|
+
async savePage(data) {
|
239
|
+
await this.dataWriter.savePage(data);
|
327
240
|
};
|
328
241
|
|
329
|
-
saveSnippet(data
|
330
|
-
|
331
|
-
const message = {};
|
332
|
-
|
333
|
-
message.action = 'saveSnippet';
|
334
|
-
message.params = {};
|
335
|
-
|
336
|
-
message.params.data = data;
|
337
|
-
|
338
|
-
this.dataWriter.intercom.send(message, options, (err, msgUuid) => {
|
339
|
-
if (err) return cb(err);
|
340
|
-
|
341
|
-
DataWriter.emitter.once(msgUuid, cb);
|
342
|
-
});
|
242
|
+
async saveSnippet(data) {
|
243
|
+
await this.dataWriter.saveSnippet(data);
|
343
244
|
}
|
344
245
|
}
|
345
246
|
|