larvitcms 2.0.0 → 3.0.2
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/.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
|
|