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/dataWriter.js CHANGED
@@ -1,25 +1,15 @@
1
1
  'use strict';
2
2
 
3
- const EventEmitter = require('events').EventEmitter;
4
- const topLogPrefix = 'larvitcms: dataWriter.js: ';
5
- const DbMigration = require('larvitdbmigration');
6
- const slugify = require('larvitslugify');
7
- const LUtils = require('larvitutils');
8
- const amsync = require('larvitamsync');
9
- const async = require('async');
3
+ const { DbMigration } = require('larvitdbmigration');
4
+ const { slugify } = require('larvitslugify');
5
+ const { Utils, Log } = require('larvitutils');
10
6
 
11
- let isReady = false;
12
- let readyInProgress = false;
13
- let emitter = new EventEmitter();
7
+ const topLogPrefix = 'larvitcms: dataWriter.js: ';
14
8
 
15
9
  class DataWriter {
16
- static get emitter() { return emitter; }
17
-
18
10
  constructor(options) {
19
11
  if (!options.log) {
20
- const tmpLUtils = new LUtils();
21
-
22
- options.log = new tmpLUtils.Log();
12
+ options.log = new Log();
23
13
  }
24
14
 
25
15
  this.options = options;
@@ -28,339 +18,113 @@ class DataWriter {
28
18
  this[key] = options[key];
29
19
  }
30
20
 
31
- this.lUtils = new LUtils({log: this.log});
32
-
33
- this.listenToQueue();
34
- }
35
-
36
- listenToQueue(retries, cb) {
37
- const logPrefix = topLogPrefix + 'listenToQueue() - ';
38
- const options = {exchange: this.exchangeName};
39
- const tasks = [];
40
-
41
- let listenMethod;
42
-
43
- if (typeof retries === 'function') {
44
- cb = retries;
45
- retries = 0;
46
- }
47
-
48
- if (typeof cb !== 'function') {
49
- cb = function () {};
50
- }
51
-
52
- if (retries === undefined) {
53
- retries = 0;
54
- }
55
-
56
- tasks.push(cb => {
57
- if (this.mode === 'master') {
58
- listenMethod = 'consume';
59
- options.exclusive = true; // It is important no other client tries to sneak
60
- // out messages from us, and we want "consume"
61
- // since we want the queue to persist even if this
62
- // minion goes offline.
63
- } else if (this.mode === 'slave' || this.mode === 'noSync') {
64
- listenMethod = 'subscribe';
65
- } else {
66
- const err = new Error('Invalid this.mode. Must be either "master", "slave" or "noSync"');
67
-
68
- this.log.error(logPrefix + err.message);
69
-
70
- return cb(err);
71
- }
72
-
73
- this.log.info(logPrefix + 'listenMethod: ' + listenMethod);
74
-
75
- cb();
76
- });
77
-
78
- tasks.push(cb => {
79
- this.ready(cb);
80
- });
81
-
82
- tasks.push(cb => {
83
- this.intercom[listenMethod](options, (message, ack, deliveryTag) => {
84
- ack(); // Ack first, if something goes wrong we log it and handle it manually
85
-
86
- if (typeof message !== 'object') {
87
- this.log.error(logPrefix + 'intercom.' + listenMethod + '() - Invalid message received, is not an object! deliveryTag: "' + deliveryTag + '"');
88
-
89
- return;
90
- }
91
-
92
- if (typeof this[message.action] === 'function') {
93
- this[message.action](message.params, deliveryTag, message.uuid);
94
- } else {
95
- this.log.warn(logPrefix + 'intercom.' + listenMethod + '() - Unknown message.action received: "' + message.action + '"');
96
- }
97
- }, cb);
98
- });
99
-
100
- async.series(tasks, cb);
21
+ this.lUtils = new Utils({log: this.log});
101
22
  }
102
23
 
103
- // This is ran before each incoming message on the queue is handeled
104
- ready(retries, cb) {
105
- const logPrefix = topLogPrefix + 'ready() - ';
106
- const tasks = [];
107
-
108
- if (typeof retries === 'function') {
109
- cb = retries;
110
- retries = 0;
111
- }
112
-
113
- if (typeof cb !== 'function') {
114
- cb = function () {};
115
- }
116
-
117
- if (retries === undefined) {
118
- retries = 0;
119
- }
24
+ async runDbMigrations() {
25
+ const options = {};
120
26
 
121
- if (isReady === true) return cb();
27
+ options.dbType = 'mariadb';
28
+ options.dbDriver = this.db;
29
+ options.tableName = 'cms_db_version';
30
+ options.migrationScriptsPath = __dirname + '/dbmigration';
31
+ const dbMigration = new DbMigration(options);
122
32
 
123
- if (readyInProgress === true) {
124
- DataWriter.emitter.on('ready', cb);
125
-
126
- return;
127
- }
128
-
129
- readyInProgress = true;
130
-
131
- tasks.push(cb => {
132
- if (this.mode === 'slave') {
133
- this.log.verbose(logPrefix + 'this.mode: "' + this.mode + '", so read');
134
-
135
- amsync.mariadb({
136
- exchange: this.exchangeName + '_dataDump',
137
- intercom: this.intercom
138
- }, cb);
139
- } else {
140
- cb();
141
- }
142
- });
143
-
144
- // Migrate database
145
- tasks.push(cb => {
146
- const options = {};
147
-
148
- let dbMigration;
149
-
150
- options.dbType = 'mariadb';
151
- options.dbDriver = this.db;
152
- options.tableName = 'cms_db_version';
153
- options.migrationScriptsPath = __dirname + '/dbmigration';
154
- dbMigration = new DbMigration(options);
155
-
156
- dbMigration.run(err => {
157
- if (err) {
158
- this.log.error(logPrefix + 'Database error: ' + err.message);
159
- }
160
-
161
- cb(err);
162
- });
163
- });
164
-
165
- async.series(tasks, err => {
166
- if (err) return;
167
-
168
- isReady = true;
169
- DataWriter.emitter.emit('ready');
170
-
171
- if (this.mode === 'master') {
172
- this.runDumpServer(cb);
173
- } else {
174
- cb();
175
- }
176
- });
33
+ await dbMigration.run();
177
34
  }
178
35
 
179
- runDumpServer(cb) {
180
- const options = {
181
- exchange: this.exchangeName + '_dataDump',
182
- host: this.options.amsync ? this.options.amsync.host : null,
183
- minPort: this.options.amsync ? this.options.amsync.minPort : null,
184
- maxPort: this.options.amsync ? this.options.amsync.maxPort : null
185
- };
186
-
187
- const args = [];
188
-
189
- if (this.db.conf.host) {
190
- args.push('-h');
191
- args.push(this.db.conf.host);
192
- }
193
-
194
- args.push('-u');
195
- args.push(this.db.conf.user);
196
-
197
- if (this.db.conf.password) {
198
- args.push('-p' + this.db.conf.password);
199
- }
200
-
201
- args.push('--single-transaction');
202
- args.push('--hex-blob');
203
- args.push(this.db.conf.database);
204
-
205
- // Tables
206
- args.push('cms_db_version');
207
- args.push('cms_pages');
208
- args.push('cms_pagesData');
209
- args.push('cms_snippets');
210
-
211
- options.dataDumpCmd = {
212
- command: 'mysqldump',
213
- args: args
214
- };
215
-
216
- options['Content-Type'] = 'application/sql';
217
- options.intercom = this.intercom;
218
-
219
- new amsync.SyncServer(options, cb);
220
- }
221
-
222
- rmPage(params, deliveryTag, msgUuid) {
36
+ async rmPage(uuid) {
223
37
  const logPrefix = topLogPrefix + 'rmPage() - ';
224
- const options = params.data;
225
- const uuidBuffer = this.lUtils.uuidToBuffer(options.uuid);
226
- const tasks = [];
38
+ const uuidBuffer = this.lUtils.uuidToBuffer(uuid);
227
39
 
228
- if (options.uuid === undefined) {
40
+ if (uuid === undefined) {
229
41
  const err = new Error('pageUuid not provided');
230
-
231
42
  this.log.warn(logPrefix + err.message);
232
-
233
- return DataWriter.emitter.emit(msgUuid, err);
43
+ throw err;
234
44
  }
235
45
 
236
46
  if (uuidBuffer === false) {
237
47
  const err = new Error('Inavlid pageUuid provided');
238
-
239
48
  this.log.warn(logPrefix + err.message);
240
-
241
- return DataWriter.emitter.emit(msgUuid, err);
49
+ throw err;
242
50
  }
243
51
 
244
- tasks.push(cb => this.ready(cb));
245
-
246
- tasks.push(cb => {
247
- this.db.query('DELETE FROM cms_pagesData WHERE pageUuid = ?', [uuidBuffer], cb);
248
- });
249
-
250
- tasks.push(cb => {
251
- this.db.query('DELETE FROM cms_pages WHERE uuid = ?', [uuidBuffer], cb);
252
- });
253
-
254
- async.series(tasks, err => {
255
- DataWriter.emitter.emit(msgUuid, err);
256
- });
52
+ await this.db.query('DELETE FROM cms_pagesData WHERE pageUuid = ?', [uuidBuffer]);
53
+ await this.db.query('DELETE FROM cms_pages WHERE uuid = ?', [uuidBuffer]);
257
54
  }
258
55
 
259
- rmSnippet(params, deliveryTag, msgUuid) {
56
+ async rmSnippet(name) {
260
57
  const logPrefix = topLogPrefix + 'rmSnippet() - ';
261
- const options = params.data;
262
- const tasks = [];
263
58
 
264
- if (!options.name) {
59
+ if (!name) {
265
60
  const err = new Error('snippet name not provided');
266
-
267
61
  this.log.warn(logPrefix + err.message);
268
-
269
- return DataWriter.emitter.emit(msgUuid, err);
62
+ throw err;
270
63
  }
271
64
 
272
- tasks.push(cb => this.ready(cb));
273
-
274
- tasks.push(cb => {
275
- this.db.query('DELETE FROM cms_snippets WHERE name = ?', [options.name], cb);
276
- });
277
-
278
- async.series(tasks, err => {
279
- DataWriter.emitter.emit(msgUuid, err);
280
- });
65
+ await this.db.query('DELETE FROM cms_snippets WHERE name = ?', [name]);
281
66
  }
282
67
 
283
- savePage(params, deliveryTag, msgUuid) {
68
+ async savePage(options) {
284
69
  const logPrefix = topLogPrefix + 'savePage() - ';
285
- const options = params.data;
286
70
  const uuidBuffer = this.lUtils.uuidToBuffer(options.uuid);
287
- const tasks = [];
288
-
289
- let lang;
290
71
 
291
72
  if (options.uuid === undefined) {
292
73
  const err = new Error('pageUuid not provided');
293
-
294
74
  this.log.warn(logPrefix + err.message);
295
-
296
- return DataWriter.emitter.emit(msgUuid, err);
75
+ throw err;
297
76
  }
298
77
 
299
78
  if (uuidBuffer === false) {
300
79
  const err = new Error('Inavlid pageUuid provided');
301
-
302
80
  this.log.warn(logPrefix + err.message);
303
-
304
- return DataWriter.emitter.emit(msgUuid, err);
81
+ throw err;
305
82
  }
306
83
 
307
- this.log.debug(logPrefix + 'Running with data. "' + JSON.stringify(params.data) + '"');
84
+ this.log.debug(logPrefix + 'Running with data. "' + JSON.stringify(options) + '"');
308
85
 
309
- tasks.push(cb => this.ready(cb));
86
+ await this.db.query('DELETE FROM cms_pagesData WHERE pageUuid = ?', [uuidBuffer]);
87
+ await this.db.query('DELETE FROM cms_pages WHERE uuid = ?', [uuidBuffer]);
310
88
 
311
- tasks.push(cb => {
312
- this.db.query('DELETE FROM cms_pagesData WHERE pageUuid = ?', [uuidBuffer], cb);
313
- });
89
+ // Insert page
90
+ const dbFields = [uuidBuffer, options.name];
314
91
 
315
- tasks.push(cb => {
316
- this.db.query('DELETE FROM cms_pages WHERE uuid = ?', [uuidBuffer], cb);
317
- });
92
+ let sql = 'INSERT INTO cms_pages (uuid,name';
318
93
 
319
- tasks.push(cb => {
320
- const dbFields = [uuidBuffer, options.name];
321
-
322
- let sql = 'INSERT INTO cms_pages (uuid,name';
323
-
324
- if (options.published) {
325
- sql += ', published';
326
- }
94
+ if (options.published) {
95
+ sql += ', published';
96
+ }
327
97
 
328
- if (options.template) {
329
- sql += ', template';
330
- }
98
+ if (options.template) {
99
+ sql += ', template';
100
+ }
331
101
 
332
- sql += ') VALUES(?,?';
102
+ sql += ') VALUES(?,?';
333
103
 
334
- if (options.published) {
335
- sql += ',?';
336
- dbFields.push(options.published);
337
- }
104
+ if (options.published) {
105
+ sql += ',?';
106
+ dbFields.push(options.published);
107
+ }
338
108
 
339
- if (options.template) {
340
- sql += ',?';
341
- dbFields.push(options.template);
342
- }
109
+ if (options.template) {
110
+ sql += ',?';
111
+ dbFields.push(options.template);
112
+ }
343
113
 
344
- sql += ');';
114
+ sql += ');';
345
115
 
346
- this.db.query(sql, dbFields, cb);
347
- });
116
+ await this.db.query(sql, dbFields);
348
117
 
349
118
  // We need to declare this outside the loop because of async operations
350
- const addEntryData = (lang, htmlTitle, body1, body2, body3, body4, body5, body6, slug) => {
351
- tasks.push(cb => {
352
- const dbFields = [uuidBuffer, lang, htmlTitle, body1, body2, body3, body4, body5, body6, slug];
353
-
354
-
355
- const sql = 'INSERT INTO cms_pagesData (pageUuid, lang, htmlTitle, body1, body2, body3, body4, body5, body6, slug) VALUES(?,?,?,?,?,?,?,?,?,?);';
356
-
357
- this.db.query(sql, dbFields, cb);
358
- });
119
+ const addEntryData = async (lang, htmlTitle, body1, body2, body3, body4, body5, body6, slug) => {
120
+ const dbFields = [uuidBuffer, lang, htmlTitle, body1, body2, body3, body4, body5, body6, slug];
121
+ const sql = 'INSERT INTO cms_pagesData (pageUuid, lang, htmlTitle, body1, body2, body3, body4, body5, body6, slug) VALUES(?,?,?,?,?,?,?,?,?,?);';
122
+ await this.db.query(sql, dbFields);
359
123
  };
360
124
 
361
125
  // Add content data
362
126
  if (options.langs) {
363
- for (lang in options.langs) {
127
+ for (const lang in options.langs) {
364
128
  if (options.langs[lang].slug) {
365
129
  options.langs[lang].slug = slugify(options.langs[lang].slug, {save: ['_', '-', '/']});
366
130
  }
@@ -377,39 +141,23 @@ class DataWriter {
377
141
  if (!options.langs[lang].body5) options.langs[lang].body5 = '';
378
142
  if (!options.langs[lang].body6) options.langs[lang].body6 = '';
379
143
 
380
- addEntryData(lang, options.langs[lang].htmlTitle, options.langs[lang].body1, options.langs[lang].body2, options.langs[lang].body3, options.langs[lang].body4, options.langs[lang].body5, options.langs[lang].body6, options.langs[lang].slug);
144
+ await addEntryData(lang, options.langs[lang].htmlTitle, options.langs[lang].body1, options.langs[lang].body2, options.langs[lang].body3, options.langs[lang].body4, options.langs[lang].body5, options.langs[lang].body6, options.langs[lang].slug);
381
145
  }
382
146
  }
383
-
384
- async.series(tasks, err => {
385
- DataWriter.emitter.emit(msgUuid, err);
386
- });
387
147
  }
388
148
 
389
- saveSnippet(params, deliveryTag, msgUuid) {
149
+ async saveSnippet(options) {
390
150
  const logPrefix = topLogPrefix + 'saveSnippet() - ';
391
- const options = params.data;
392
151
  const sql = 'REPLACE INTO cms_snippets (body, name, lang) VALUES(?,?,?);';
393
152
  const dbFields = [options.body, options.name, options.lang];
394
- const tasks = [];
395
153
 
396
154
  if (options.name === undefined) {
397
155
  const err = new Error('Name not provided');
398
-
399
156
  this.log.warn(logPrefix + err.message);
400
-
401
- return DataWriter.emitter.emit(msgUuid, err);
157
+ throw err;
402
158
  }
403
159
 
404
- tasks.push(cb => this.ready(cb));
405
-
406
- tasks.push(cb => {
407
- this.db.query(sql, dbFields, cb);
408
- });
409
-
410
- async.series(tasks, err => {
411
- DataWriter.emitter.emit(msgUuid, err);
412
- });
160
+ await this.db.query(sql, dbFields);
413
161
  }
414
162
  }
415
163
 
package/dbmigration/5.js CHANGED
@@ -1,30 +1,20 @@
1
1
  'use strict';
2
2
 
3
3
  const uuidLib = require('uuid');
4
- const lUtils = require('larvitutils');
5
- const async = require('async');
6
- const db = require('larvitdb');
4
+ const { Utils } = require('larvitutils');
7
5
 
8
- exports = module.exports = function (cb) {
9
- const tasks = [];
6
+ exports = module.exports = async context => {
7
+ const { db } = context;
10
8
 
11
- db.query('SELECT id FROM cms_pages WHERE uuid IS NULL', function (err, rows) {
12
- if (err) return cb(err);
9
+ const { rows } = await db.query('SELECT id FROM cms_pages WHERE uuid IS NULL');
10
+ if (rows.length === 0) return;
13
11
 
14
- if (rows.length === 0) return cb();
12
+ const lUtils = new Utils();
15
13
 
16
- for (const r of rows) {
17
- const uuid = lUtils.uuidToBuffer(uuidLib.v1());
14
+ for (const r of rows) {
15
+ const uuid = lUtils.uuidToBuffer(uuidLib.v1());
18
16
 
19
- tasks.push(function (cb) {
20
- db.query('UPDATE cms_pages SET uuid = ? WHERE id = ?', [uuid, r.id], cb);
21
- });
22
-
23
- tasks.push(function (cb) {
24
- db.query('UPDATE cms_pagesData SET pageUuid = ? WHERE pageId = ?', [uuid, r.id], cb);
25
- });
26
- }
27
-
28
- async.series(tasks, cb);
29
- });
17
+ await db.query('UPDATE cms_pages SET uuid = ? WHERE id = ?', [uuid, r.id]);
18
+ await db.query('UPDATE cms_pagesData SET pageUuid = ? WHERE pageId = ?', [uuid, r.id]);
19
+ }
30
20
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "larvitcms",
3
- "version": "2.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Simple blog module with admin GUI for larvitadmingui",
5
5
  "author": {
6
6
  "name": "Mikael 'Lilleman' Göransson",
@@ -9,25 +9,17 @@
9
9
  },
10
10
  "private": false,
11
11
  "dependencies": {
12
- "async": "^3.0.1",
13
- "larvitamintercom": "^0.3.4",
14
- "larvitamsync": "^0.7.3",
15
- "larvitdb": "^2.1.1",
16
- "larvitdbmigration": "^4.0.2",
17
- "larvitfs": "^2.3.1",
18
- "larvitslugify": "^1.0.0",
19
- "larvitutils": "^2.1.0",
20
- "lodash": "^4.17.4",
21
- "randomstring": "^1.1.5",
22
- "uuid": "^3.1.0"
12
+ "larvitdb": "3.2.4",
13
+ "larvitdbmigration": "7.0.1",
14
+ "larvitslugify": "2.0.1",
15
+ "larvitutils": "5.0.5",
16
+ "lodash": "4.17.21",
17
+ "uuid": "8.3.2"
23
18
  },
24
19
  "devDependencies": {
25
- "larvitruncmd": "github:larvit/larvitruncmd",
26
- "mocha": "6.1.4",
27
- "mocha-eslint": "5.0.0",
28
- "request": "2.88.0",
29
- "validator": "11.0.0",
30
- "wait-for-port": "0.0.2"
20
+ "eslint": "8.13.0",
21
+ "mocha": "9.2.2",
22
+ "nyc": "15.1.0"
31
23
  },
32
24
  "keywords": [
33
25
  "cms"
@@ -43,7 +35,10 @@
43
35
  },
44
36
  "homepage": "https://github.com/larvit/larvitcms",
45
37
  "scripts": {
46
- "test": "mocha"
38
+ "lint": "eslint *.js test/*.js dbmigration/*.js",
39
+ "test:unit": "mocha --exit --bail './test/*.js'",
40
+ "coverage": "nyc --reporter lcov npm run test:unit",
41
+ "test": "npm run lint && npm run coverage"
47
42
  },
48
43
  "license": "MIT",
49
44
  "maintainers": [
package/renovate.json CHANGED
@@ -1,9 +1,4 @@
1
1
  {
2
- "extends": [
3
- "config:base"
4
- ],
5
- "automerge": true,
6
- "major": {
7
- "automerge": false
8
- }
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": ["github>larvit/standards:renovate-default"]
9
4
  }