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 CHANGED
@@ -1,88 +1,86 @@
1
1
  {
2
- "root": true,
3
- "env": {
4
- "es6": true,
5
- "mocha": true,
6
- "node": true
7
- },
8
- "rules": {
9
- "array-bracket-newline": ["error", "consistent"],
10
- "array-bracket-spacing": ["error", "never"],
11
- "block-spacing": ["error", "always"],
12
- "brace-style": ["error", "1tbs", {"allowSingleLine": true}],
13
- "capitalized-comments": ["error", "always", {"ignoreConsecutiveComments": true}],
14
- "comma-dangle": ["error", "never"],
15
- "comma-spacing": ["error", {"before": false, "after": true}],
16
- "comma-style": ["error", "last"],
17
- "computed-property-spacing": ["error", "never"],
18
- "consistent-this": ["error", "that"],
19
- "eol-last": ["error", "always"],
20
- "eqeqeq": ["warn", "always"],
21
- "func-call-spacing": ["error", "never"],
22
- "func-style": ["error", "declaration", {"allowArrowFunctions": true}],
23
- "function-paren-newline": ["error", "multiline"],
24
- "indent": ["error", "tab"],
25
- "key-spacing": [
26
- "error",
27
- {"beforeColon": false, "afterColon": true, "mode": "strict"}
28
- ],
29
- "keyword-spacing": ["error", {"before": true, "after": true}],
30
- "linebreak-style": ["error", "unix"],
31
- "lines-around-comment": ["error", {"beforeBlockComment": true, "afterBlockComment": false}],
32
- "lines-between-class-members": ["error", "always"],
33
- "multiline-ternary": ["error", "never"],
34
- "new-cap": ["error"],
35
- "new-parens": ["error"],
36
- "newline-per-chained-call": ["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
- "padded-blocks": ["error", "never"],
64
- "padding-line-between-statements": [
65
- "error",
66
- {"blankLine": "always", "prev": "*", "next": "return"},
67
- {"blankLine": "always", "prev": ["const", "let"], "next": "*"},
68
- {"blankLine": "any", "prev": ["const", "let"], "next": ["const", "let"]}
69
- ],
70
- "quote-props": ["error", "as-needed"],
71
- "quotes": ["error", "single"],
72
- "semi-spacing": ["error", {"before": false, "after": true}],
73
- "semi-style": ["error", "last"],
74
- "semi": ["error", "always"],
75
- "space-before-blocks": ["error", "always"],
76
- "space-before-function-paren": ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}],
77
- "space-in-parens": ["error", "never"],
78
- "space-infix-ops": ["error"],
79
- "space-unary-ops": ["error", {"words": true, "nonwords": false}],
80
- "spaced-comment": ["error", "always"],
81
- "strict": ["error", "global"],
82
- "template-tag-spacing": ["error", "never"],
83
- "unicode-bom": ["error", "never"],
84
- "valid-jsdoc": ["error", {"requireReturn": false}],
85
- "valid-typeof": ["error"],
86
- "vars-on-top": ["off"]
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
@@ -1,2 +1,4 @@
1
+ [![Build Status](https://github.com/larvit/larvitcms/actions/workflows/ci.yml/badge.svg)](https://github.com/larvit/larvitcms/actions)
2
+
1
3
  # larvitcms
2
4
  Very simple and basic CMS backend and admin page
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 LUtils = require('larvitutils');
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 LUtils();
15
+ if (!options.lUtils) options.lUtils = new Utils();
18
16
 
19
17
  if (!this.options.log) {
20
- const lUtils = new LUtils();
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
- ready(cb) {
65
- this.dataWriter.ready(cb);
33
+ async runDbMigrations() {
34
+ await this.dataWriter.runDbMigrations();
66
35
  }
67
36
 
68
- getPages(options, cb) {
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
- if (typeof options === 'function') {
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, (err, rows) => {
175
- if (err) return cb(err);
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
- if (tmpPages[uuid] === undefined) {
181
- tmpPages[uuid] = {
182
- uuid: uuid,
183
- name: rows[i].name,
184
- published: Boolean(rows[i].published),
185
- template: rows[i].template,
186
- langs: {}
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
- for (const pageUuid in tmpPages) {
202
- pages.push(tmpPages[pageUuid]);
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
- cb(null, pages);
206
- });
163
+ for (const pageUuid in tmpPages) {
164
+ pages.push(tmpPages[pageUuid]);
165
+ }
166
+
167
+ return pages;
207
168
  };
208
169
 
209
- getSnippets(options, cb) {
210
- this.ready(() => {
211
- const dbFields = [];
212
- let sql;
170
+ async getSnippets(options) {
171
+ options = options || {};
213
172
 
214
- if (typeof options === 'function') {
215
- cb = options;
216
- options = {};
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
- if (options.onlyNames) {
220
- sql = 'SELECT DISTINCT name FROM cms_snippets ORDER BY name;';
221
- this.db.query(sql, cb);
178
+ const dbFields = [];
179
+ let sql = 'SELECT * FROM cms_snippets\n';
180
+ sql += 'WHERE 1 + 1\n';
222
181
 
223
- return;
182
+ if (options.names !== undefined) {
183
+ if (typeof options.names === 'string') {
184
+ options.names = [options.names];
224
185
  }
225
186
 
226
- sql = 'SELECT * FROM cms_snippets\n';
227
- sql += 'WHERE 1 + 1\n';
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 += 'ORDER BY name, lang';
249
-
250
- this.db.query(sql, dbFields, (err, rows) => {
251
- const snippets = [];
191
+ sql += ' AND name IN (';
252
192
 
253
- let snippet;
254
- let prevName;
193
+ for (let i = 0; options.names[i] !== undefined; i++) {
194
+ sql += '?,';
195
+ dbFields.push(options.names[i]);
196
+ }
255
197
 
256
- if (err) return cb(err);
198
+ sql = sql.substring(0, sql.length - 1) + ')\n';
199
+ }
257
200
 
258
- for (let i = 0; rows[i] !== undefined; i++) {
259
- if (prevName !== rows[i].name) {
260
- if (snippet) {
261
- snippets.push(snippet);
262
- }
201
+ sql += 'ORDER BY name, lang';
263
202
 
264
- snippet = {name: rows[i].name, langs: {}};
265
- }
203
+ const { rows } = await this.db.query(sql, dbFields);
204
+ const snippets = [];
266
205
 
267
- prevName = rows[i].name;
268
- snippet.langs[rows[i].lang] = rows[i].body;
269
- }
206
+ let snippet;
207
+ let prevName;
270
208
 
271
- // Add the last one
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
- cb(null, snippets);
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
- message.params.data = {uuid: uuid};
218
+ prevName = rows[i].name;
219
+ snippet.langs[rows[i].lang] = rows[i].body;
220
+ }
289
221
 
290
- this.dataWriter.intercom.send(message, options, (err, msgUuid) => {
291
- if (err) return cb(err);
222
+ // Add the last one
223
+ if (snippet) {
224
+ snippets.push(snippet);
225
+ }
292
226
 
293
- DataWriter.emitter.once(msgUuid, cb);
294
- });
227
+ return snippets;
295
228
  }
296
229
 
297
- rmSnippet(name, cb) {
298
- const options = {exchange: this.exchangeName};
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
- savePage(data, cb) {
314
- const options = {exchange: this.exchangeName};
315
- const message = {};
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
- DataWriter.emitter.once(msgUuid, cb);
326
- });
238
+ async savePage(data) {
239
+ await this.dataWriter.savePage(data);
327
240
  };
328
241
 
329
- saveSnippet(data, cb) {
330
- const options = {exchange: this.exchangeName};
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