museria 0.2.49 → 0.3.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.
Files changed (74) hide show
  1. package/.eslintrc +10 -2
  2. package/.github/workflows/build.yml +3 -3
  3. package/.github/workflows/publish.yml +3 -3
  4. package/README.md +55 -59
  5. package/bin/actions.js +28 -28
  6. package/bin/index.js +4 -4
  7. package/bin/runner.js +1 -1
  8. package/bin/utils.js +6 -2
  9. package/dist/client/museria.client.js +7 -7
  10. package/dist/face/45a265d0f07b31cde85f.ttf +0 -0
  11. package/dist/face/6205fd00fb1b573e9f0f.ttf +0 -0
  12. package/dist/face/8d3cabfc66809162fb4d.woff2 +0 -0
  13. package/dist/face/fb8184add5a3101ad0a3.woff2 +0 -0
  14. package/dist/face/museria.face.js +33 -13
  15. package/dist/face/style.css +13 -11
  16. package/package.json +41 -40
  17. package/src/browser/client/index.js +2 -1
  18. package/src/browser/face/client.js +2 -1
  19. package/src/browser/face/controllers/app/app.html +77 -69
  20. package/src/browser/face/controllers/app/app.js +14 -7
  21. package/src/browser/face/controllers/app/app.scss +2 -22
  22. package/src/browser/face/index.js +3 -3
  23. package/src/browser/face/styles/main.scss +91 -11
  24. package/src/browser/face/styles/vars.scss +0 -1
  25. package/src/client.js +73 -74
  26. package/src/collection/transports/music/index.js +20 -18
  27. package/src/db/transports/database/index.js +7 -5
  28. package/src/db/transports/loki/index.js +30 -25
  29. package/src/errors.js +2 -1
  30. package/src/index.js +8 -6
  31. package/src/node.js +312 -323
  32. package/src/schema.js +27 -29
  33. package/src/server/transports/express/api/butler/controllers.js +7 -10
  34. package/src/server/transports/express/api/butler/routes.js +5 -5
  35. package/src/server/transports/express/api/master/controllers.js +7 -10
  36. package/src/server/transports/express/api/master/routes.js +5 -5
  37. package/src/server/transports/express/api/node/controllers.js +52 -61
  38. package/src/server/transports/express/api/node/routes.js +10 -10
  39. package/src/server/transports/express/api/routes.js +1 -1
  40. package/src/server/transports/express/api/slave/controllers.js +7 -10
  41. package/src/server/transports/express/api/slave/routes.js +6 -6
  42. package/src/server/transports/express/client/controllers.js +40 -61
  43. package/src/server/transports/express/client/routes.js +33 -39
  44. package/src/server/transports/express/controllers.js +10 -21
  45. package/src/server/transports/express/index.js +23 -20
  46. package/src/server/transports/express/midds.js +67 -67
  47. package/src/server/transports/express/routes.js +12 -12
  48. package/src/utils.js +175 -184
  49. package/test/client.js +311 -305
  50. package/test/db/database.js +32 -28
  51. package/test/db/loki.js +78 -74
  52. package/test/group.js +161 -156
  53. package/test/index.js +20 -10
  54. package/test/node.js +461 -460
  55. package/test/routes.js +404 -399
  56. package/test/server/express.js +35 -31
  57. package/test/services.js +25 -18
  58. package/test/tools.js +8 -6
  59. package/test/utils.js +236 -234
  60. package/webpack.client.js +9 -7
  61. package/webpack.face.js +8 -6
  62. package/dist/face/fa-brands-400.eot +0 -0
  63. package/dist/face/fa-brands-400.svg +0 -3717
  64. package/dist/face/fa-brands-400.ttf +0 -0
  65. package/dist/face/fa-brands-400.woff +0 -0
  66. package/dist/face/fa-brands-400.woff2 +0 -0
  67. package/dist/face/fa-solid-900.eot +0 -0
  68. package/dist/face/fa-solid-900.svg +0 -5034
  69. package/dist/face/fa-solid-900.ttf +0 -0
  70. package/dist/face/fa-solid-900.woff +0 -0
  71. package/dist/face/fa-solid-900.woff2 +0 -0
  72. /package/dist/face/{open-sans.ttf → 17e98b9e5586529b13cc.ttf} +0 -0
  73. /package/dist/face/{proxima-nova.ttf → 326601dfabd91e3f016c.ttf} +0 -0
  74. /package/dist/face/{logo.svg → ee9c6af64aa224827cec.svg} +0 -0
package/src/utils.js CHANGED
@@ -1,18 +1,17 @@
1
- const NodeID3 = require('node-id3');
2
- const fs = require('fs');
3
- const pick = require('lodash/pick');
4
- const stUtils = require('storacle/src/utils');
5
- const mtUtils = require('metastocle/src/utils');
6
- const utils = Object.assign({}, stUtils, mtUtils);
7
- const emojiStrip = require('emoji-strip');
8
- const mm = require('music-metadata');
9
- const base64url = require('base64url');
10
-
1
+ import NodeID3 from "node-id3";
2
+ import fse from "fs-extra";
3
+ import pick from "lodash-es/pick.js";
4
+ import utilsStoracle from "storacle/src/utils.js";
5
+ import utilsMetastocle from "metastocle/src/utils.js";
6
+ import emojiStrip from "emoji-strip";
7
+ import mm from "music-metadata";
8
+ import base64url from "base64url";
9
+
10
+ const utils = Object.assign({}, utilsStoracle, utilsMetastocle);
11
11
  utils.regexSongLinks = /(([a-z]+:\/\/)?[-\p{L}\p{N}]+\.[\p{L}]{2,}|[a-z]+:\/\/(\[:*[\w\d]+:[\w\d:]+\]|\d+\.[\d.]+))\S*/igu;
12
12
  utils.regexSongFeats = /[([\s]+((ft\.|feat\.)[\s]+((?!(\s+[-([)\]]+))[^)\]])+)\s*[)\]]*([\s]+[-([]+|$)/iu;
13
-
14
13
  utils.heritableSongTags = [
15
- 'TALB', 'TCOM', 'TCON', 'TCOP', 'TDAT', 'TEXT', 'TIT1', 'TIT3', 'TLAN',
14
+ 'TALB', 'TCOM', 'TCON', 'TCOP', 'TDAT', 'TEXT', 'TIT1', 'TIT3', 'TLAN',
16
15
  'TOAL', 'TOLY', 'TOPE', 'TORY', 'TPE2', 'TPE3', 'TPE4', 'APIC'
17
16
  ];
18
17
 
@@ -23,51 +22,48 @@ utils.MusicDocumentsHandler = class extends utils.DocumentsHandler {
23
22
  $mus(value, filter) {
24
23
  return utils.getSongSimilarity(value, filter.value, { min: filter.similarity, beautify: filter.beautify }) >= filter.similarity;
25
24
  }
26
-
27
25
  $art(value, filter) {
28
26
  filter = filter.toLowerCase();
29
27
  const artists = utils.getSongArtists(value);
30
28
  return !!artists.find(a => a.toLowerCase() == filter);
31
29
  }
32
-
33
- $milk(value, filter) {
34
- if(/^\s*[(]?(feat[.]?|remix?)\s*$/i.test(filter)) {
30
+ $milk(value, filter) {
31
+ if (/^\s*[(]?(feat[.]?|remix?)\s*$/i.test(filter)) {
35
32
  return false;
36
33
  }
37
-
38
34
  return this.$ilk(value, filter);
39
35
  }
40
- }
36
+ };
41
37
 
42
38
  /**
43
- * @see stUtils.getFileInfo
39
+ * @see utilsStoracle.getFileInfo
44
40
  */
45
41
  utils.getFileInfo = async function () {
46
- const info = await stUtils.getFileInfo.apply(this, arguments);
42
+ const info = await utilsStoracle.getFileInfo.apply(this, arguments);
47
43
  info.ext == 'mpga' && (info.ext = 'mp3');
48
44
  return info;
49
- }
45
+ };
50
46
 
51
47
  /**
52
48
  * Check the link is valid as an audio
53
- *
54
- * @see stUtils.isValidFileLink
49
+ *
50
+ * @see utilsStoracle.isValidFileLink
55
51
  */
56
52
  utils.isValidSongAudioLink = function (link) {
57
- if(typeof link != 'string' || !link.split('?')[0].match(/\.(mp3|mpeg|mpga)$/i)) {
53
+ if (typeof link != 'string' || !link.split('?')[0].match(/\.(mp3|mpeg|mpga)$/i)) {
58
54
  return false;
59
55
  }
60
56
 
61
- return this.isValidFileLink(link, { action: 'audio'})
57
+ return this.isValidFileLink(link, { action: 'audio' });
62
58
  };
63
59
 
64
60
  /**
65
61
  * Check the link is valid as a cover
66
- *
67
- * @see stUtils.isValidFileLink
62
+ *
63
+ * @see utilsStoracle.isValidFileLink
68
64
  */
69
65
  utils.isValidSongCoverLink = function (link) {
70
- if(typeof link != 'string' || !link.split('?')[0].match(/\.(jpe?g|png|jfif)$/i)) {
66
+ if (typeof link != 'string' || !link.split('?')[0].match(/\.(jpe?g|png|jfif)$/i)) {
71
67
  return false;
72
68
  }
73
69
 
@@ -76,46 +72,46 @@ utils.isValidSongCoverLink = function (link) {
76
72
 
77
73
  /**
78
74
  * Prepare the string to find songs
79
- *
75
+ *
80
76
  * @param {string} str
81
- * @returns {string}
77
+ * @returns {string}
82
78
  */
83
79
  utils.prepareSongFindingString = function (str) {
84
- if(typeof str != 'string') {
80
+ if (typeof str != 'string') {
85
81
  return '';
86
82
  }
87
-
83
+
88
84
  str = this.prepareComparisonSongTitle(str, { beautify: false })
89
85
  .trim()
90
86
  .replace(/[–—]+/g, '-')
91
87
  .replace(/[\sᅠ]+/g, ' ');
92
88
  return str;
93
- }
89
+ };
94
90
 
95
91
  /**
96
92
  * Split the song title
97
- *
93
+ *
98
94
  * @param {string} title
99
- * @returns {string[]}
95
+ * @returns {string[]}
100
96
  */
101
97
  utils.splitSongTitle = function (title) {
102
- if(typeof title != 'string') {
98
+ if (typeof title != 'string') {
103
99
  return ['', ''];
104
100
  }
105
101
 
106
102
  const delim = ' - ';
107
103
  const arr = title.split(delim);
108
104
  return [arr[0], arr.slice(1).join(delim)];
109
- }
105
+ };
110
106
 
111
107
  /**
112
108
  * Beautify the song title
113
- *
109
+ *
114
110
  * @param {string} title
115
- * @returns {string}
111
+ * @returns {string}
116
112
  */
117
113
  utils.beautifySongTitle = function (title) {
118
- if(typeof title != 'string') {
114
+ if (typeof title != 'string') {
119
115
  return '';
120
116
  }
121
117
 
@@ -125,17 +121,17 @@ utils.beautifySongTitle = function (title) {
125
121
  .replace(/[\sᅠ]+/g, ' ')
126
122
  .replace(/([([])\s+/g, '$1')
127
123
  .replace(/\s+([)\]])/g, '$1')
128
- .replace(/([([]+)(featuring|feat|ft)(\s)/ig, '$1feat.$3')
124
+ .replace(/([([]+)(featuring|feat|ft)(\s)/ig, '$1feat.$3')
129
125
  .replace(/([([\s]+)(feat\.|ft\.)(\s)/ig, '$1feat.$3')
130
126
  .toLowerCase();
131
-
132
- if(!/[^\s]+ - [^\s]+/.test(title)) {
127
+
128
+ if (!/[^\s]+ - [^\s]+/.test(title)) {
133
129
  return '';
134
130
  }
135
-
131
+
136
132
  const arr = title.split(/\(?feat\./i);
137
133
 
138
- if(arr.length > 2) {
134
+ if (arr.length > 2) {
139
135
  arr.splice(2, arr.length - 2);
140
136
  title = arr.join('(feat.').trim();
141
137
  }
@@ -145,60 +141,60 @@ utils.beautifySongTitle = function (title) {
145
141
  const mainArtist = artists[0];
146
142
  artists.shift();
147
143
 
148
- if(!mainArtist) {
144
+ if (!mainArtist) {
149
145
  return '';
150
146
  }
151
-
147
+
152
148
  const match = sides[1].match(this.regexSongFeats);
153
- let feats = (match? match[1]: '').replace(/,([^\s])/, ', $1').trim();
149
+ let feats = (match ? match[1] : '').replace(/,([^\s])/, ', $1').trim();
154
150
  title = `${mainArtist} - ${sides[1]}`;
155
- title = title.replace(this.regexSongFeats, '$5');
151
+ title = title.replace(this.regexSongFeats, '$5');
156
152
  feats && (artists = artists.concat(feats.replace(/feat\./i, '').split(',')));
157
153
  artists = [...new Set(artists.map(a => a.trim()).filter(v => v))];
158
-
159
- if(artists.length) {
160
- feats = `feat. ${ artists.join(', ') }`;
161
- }
162
154
 
155
+ if (artists.length) {
156
+ feats = `feat. ${artists.join(', ')}`;
157
+ }
158
+
163
159
  feats && (title += ` (${feats})`);
164
160
  title = title
165
161
  .replace(/\[\]|\(\)/g, '')
166
- .replace(/\s+/g, ' ')
162
+ .replace(/\s+/g, ' ')
167
163
  .split(' ')
168
- .map(p => p? (p[0].toUpperCase() + p.slice(1)): p)
164
+ .map(p => p ? (p[0].toUpperCase() + p.slice(1)) : p)
169
165
  .join(' ')
170
- .trim();
166
+ .trim();
171
167
  return title;
172
168
  };
173
169
 
174
170
  /**
175
171
  * Prepare a comparison song title
176
- *
172
+ *
177
173
  * @param {string} title
178
174
  * @returns {string}
179
175
  */
180
- utils.prepareComparisonSongTitle = function (title, options = {}) {
181
- if(typeof title != 'string') {
176
+ utils.prepareComparisonSongTitle = function (title, options = {}) {
177
+ if (typeof title != 'string') {
182
178
  return '';
183
179
  }
184
-
180
+
185
181
  options.beautify !== false && (title = this.beautifySongTitle(title));
186
182
  return this.stringifyNumbers(this.normalizeString(title));
187
- }
183
+ };
188
184
 
189
185
  /**
190
186
  * Check it is a right song title
191
- *
187
+ *
192
188
  * @param {string} title
193
189
  * @param {object} [options]
194
- * @returns {boolean}
190
+ * @returns {boolean}
195
191
  */
196
192
  utils.isSongTitle = function (title, options = {}) {
197
- if(options.beautify || options.beautify === undefined) {
193
+ if (options.beautify || options.beautify === undefined) {
198
194
  title = this.beautifySongTitle(title);
199
195
  }
200
196
 
201
- if(typeof title != 'string' || Buffer.byteLength(title) > 1024) {
197
+ if (typeof title != 'string' || Buffer.byteLength(title) > 1024) {
202
198
  return false;
203
199
  }
204
200
 
@@ -207,76 +203,76 @@ utils.isSongTitle = function (title, options = {}) {
207
203
 
208
204
  /**
209
205
  * Get the song name
210
- *
206
+ *
211
207
  * @param {string} title
212
208
  * @param {object} [options]
213
- * @returns {string}
209
+ * @returns {string}
214
210
  */
215
- utils.getSongName = function (title, options = {}) {
216
- if(options.beautify || options.beautify === undefined) {
211
+ utils.getSongName = function (title, options = {}) {
212
+ if (options.beautify || options.beautify === undefined) {
217
213
  title = this.beautifySongTitle(title);
218
214
  }
219
215
 
220
- if(!this.isSongTitle(title, { beautify: false })) {
216
+ if (!this.isSongTitle(title, { beautify: false })) {
221
217
  return '';
222
218
  }
223
-
219
+
224
220
  return (this.splitSongTitle(title)[1] || '').replace(this.regexSongFeats, '$5').trim();
225
221
  };
226
222
 
227
223
  /**
228
224
  * Get the song artists
229
- *
225
+ *
230
226
  * @param {string} title
231
227
  * @param {object} [options]
232
- * @returns {string[]}
228
+ * @returns {string[]}
233
229
  */
234
- utils.getSongArtists = function (title, options = {}) {
235
- if(options.beautify || options.beautify === undefined) {
230
+ utils.getSongArtists = function (title, options = {}) {
231
+ if (options.beautify || options.beautify === undefined) {
236
232
  title = this.beautifySongTitle(title);
237
233
  }
238
234
 
239
- if(!this.isSongTitle(title, { beautify: false })) {
235
+ if (!this.isSongTitle(title, { beautify: false })) {
240
236
  return [];
241
237
  }
242
238
 
243
239
  const sides = this.splitSongTitle(title);
244
240
  let artists = sides[0].split(/,/);
245
241
  const match = title.match(this.regexSongFeats);
246
- let feats = (match? match[1]: '').replace(/^feat\./i, '');
242
+ let feats = (match ? match[1] : '').replace(/^feat\./i, '');
247
243
  return [...new Set(artists.concat(feats.split(',')).map(v => v.trim()).filter(v => v))];
248
244
  };
249
245
 
250
246
  /**
251
247
  * Get the song similarity
252
- *
248
+ *
253
249
  * @param {string} source
254
250
  * @param {string} target
255
251
  * @param {object} [options]
256
- * @returns {float}
252
+ * @returns {float}
257
253
  */
258
254
  utils.getSongSimilarity = function (source, target, options = {}) {
259
255
  const tp = options.titlePriority || 0.5;
260
-
261
- if(options.beautify || options.beautify === undefined) {
256
+
257
+ if (options.beautify || options.beautify === undefined) {
262
258
  source = this.beautifySongTitle(source);
263
259
  target = this.beautifySongTitle(target);
264
260
  }
265
261
 
266
262
  source = source.toLowerCase();
267
263
  target = target.toLowerCase();
268
-
269
- if(!source || !target) {
264
+
265
+ if (!source || !target) {
270
266
  return 0;
271
267
  }
272
-
268
+
273
269
  const min = options.min || 0;
274
270
  const mcoef = (min - 0.5) / 0.5;
275
271
  const sourceName = this.getSongName(source, { beautify: false });
276
272
  const targetName = this.getSongName(target, { beautify: false });
277
273
  const t = this.getStringSimilarity(sourceName, targetName, { min: mcoef });
278
-
279
- if(min && !t) {
274
+
275
+ if (min && !t) {
280
276
  return 0;
281
277
  }
282
278
 
@@ -286,28 +282,27 @@ utils.getSongSimilarity = function (source, target, options = {}) {
286
282
  const targets = targetArtists.join(',');
287
283
  const a = this.getStringSimilarity(sources, targets);
288
284
  const res = (t * (1 + tp) + a * (1 - tp)) / 2;
289
- return res >= min? res: 0;
285
+ return res >= min ? res : 0;
290
286
  };
291
287
 
292
288
  /**
293
289
  * Create the song tags
294
- *
290
+ *
295
291
  * @param {object} [tags]
296
292
  * @returns {object}
297
293
  */
298
294
  utils.createSongTags = function (tags = {}) {
299
295
  const obj = {};
300
296
  const self = this;
301
-
302
297
  Object.defineProperty(obj, 'fullTitle', {
303
298
  enumerable: false,
304
299
  get: function () {
305
- return `${ this.TPE1 || '' } - ${ this.TIT2 || '' }`;
300
+ return `${this.TPE1 || ''} - ${this.TIT2 || ''}`;
306
301
  },
307
302
  set: function (val) {
308
303
  const title = self.beautifySongTitle(val);
309
-
310
- if(!title) {
304
+
305
+ if (!title) {
311
306
  delete this.TPE1;
312
307
  delete this.TIT2;
313
308
  return;
@@ -319,7 +314,7 @@ utils.createSongTags = function (tags = {}) {
319
314
  }
320
315
  });
321
316
 
322
- for(let key in tags) {
317
+ for (let key in tags) {
323
318
  obj[key] = tags[key];
324
319
  }
325
320
 
@@ -328,7 +323,7 @@ utils.createSongTags = function (tags = {}) {
328
323
 
329
324
  /**
330
325
  * Merge the song tags
331
- *
326
+ *
332
327
  * @param {object} source
333
328
  * @param {object} dest
334
329
  * @returns {object}
@@ -346,42 +341,42 @@ utils.mergeSongTags = function (source, dest) {
346
341
 
347
342
  /**
348
343
  * Prepare the song tags to get
349
- *
344
+ *
350
345
  * @async
351
346
  * @param {object} tags
352
347
  * @returns {object}
353
348
  */
354
349
  utils.prepareSongTagsToGet = async function (tags) {
355
350
  tags = this.createSongTags(tags);
356
-
357
- if(tags.APIC && typeof tags.APIC == 'object' && !Buffer.isBuffer(tags.APIC)) {
351
+
352
+ if (tags.APIC && typeof tags.APIC == 'object' && !Buffer.isBuffer(tags.APIC)) {
358
353
  tags.APIC = tags.APIC.imageBuffer;
359
- }
354
+ }
360
355
 
361
356
  return tags;
362
357
  };
363
358
 
364
359
  /**
365
360
  * Prepare the song tags to set
366
- *
361
+ *
367
362
  * @async
368
363
  * @param {object} tags
369
364
  * @returns {object}
370
365
  */
371
366
  utils.prepareSongTagsToSet = async function (tags) {
372
367
  tags = this.createSongTags(tags);
373
-
374
- if(tags.image) {
368
+
369
+ if (tags.image) {
375
370
  tags.APIC = tags.image;
376
371
  delete tags.image;
377
372
  }
378
-
379
- if(this.isFileReadStream(tags.APIC)) {
373
+
374
+ if (this.isFileReadStream(tags.APIC)) {
380
375
  tags.APIC.destroy();
381
- tags.APIC = tags.APIC.path;
376
+ tags.APIC = tags.APIC.path;
382
377
  }
383
378
 
384
- if(typeof Blob == 'function' && tags.APIC instanceof Blob) {
379
+ if (typeof Blob == 'function' && tags.APIC instanceof Blob) {
385
380
  tags.APIC = await this.blobToBuffer(tags.APIC);
386
381
  }
387
382
 
@@ -390,76 +385,74 @@ utils.prepareSongTagsToSet = async function (tags) {
390
385
 
391
386
  /**
392
387
  * Prepare the song Blob file
393
- *
388
+ *
394
389
  * @async
395
390
  * @param {Buffer} buffer
396
- * @param {Blob|File} blob
391
+ * @param {Blob|File} blob
397
392
  * @returns {Blob|File}
398
393
  */
399
394
  utils.prepareSongBlobFile = async function (buffer, blob) {
400
395
  const opts = { type: blob.type };
401
- return blob instanceof File? new File([buffer], blob.name, opts): new Blob([buffer], opts);
396
+ return blob instanceof File ? new File([buffer], blob.name, opts) : new Blob([buffer], opts);
402
397
  };
403
398
 
404
399
  /**
405
400
  * Get the song tags
406
- *
401
+ *
407
402
  * @async
408
- * @param {string|Buffer|fs.ReadStream|Blob} file
409
- * @returns {object}
403
+ * @param {string|Buffer|fse.ReadStream|Blob} file
404
+ * @returns {object}
410
405
  */
411
- utils.getSongTags = async function (file) {
412
- if(typeof Blob == 'function' && file instanceof Blob) {
406
+ utils.getSongTags = async function (file) {
407
+ if (typeof Blob == 'function' && file instanceof Blob) {
413
408
  file = await this.blobToBuffer(file);
414
409
  }
415
-
416
- if(Buffer.isBuffer(file)) {
410
+
411
+ if (Buffer.isBuffer(file)) {
417
412
  const tags = NodeID3.read(file);
418
- return await this.prepareSongTagsToGet(tags? tags.raw: {});
413
+ return await this.prepareSongTagsToGet(tags ? tags.raw : {});
419
414
  }
420
415
 
421
416
  return new Promise((resolve, reject) => {
422
417
  NodeID3.read(file.path || file, async (err, tags) => {
423
- if(err) {
418
+ if (err) {
424
419
  return reject(err);
425
420
  }
426
-
427
421
  resolve(await this.prepareSongTagsToGet(tags.raw || {}));
428
422
  });
429
- });
423
+ });
430
424
  };
431
425
 
432
426
  /**
433
427
  * Get the song tags
434
- *
428
+ *
435
429
  * @async
436
- * @param {string|Buffer|fs.ReadStream|Blob} file
430
+ * @param {string|Buffer|fse.ReadStream|Blob} file
437
431
  * @param {object} tags
438
- * @returns {string|Buffer|fs.ReadStream|Blob}
432
+ * @returns {string|Buffer|fse.ReadStream|Blob}
439
433
  */
440
434
  utils.setSongTags = async function (file, tags) {
441
435
  tags = await this.prepareSongTagsToSet(tags);
442
-
443
- if(typeof Blob == 'function' && file instanceof Blob) {
436
+
437
+ if (typeof Blob == 'function' && file instanceof Blob) {
444
438
  const buffer = NodeID3.write(tags, await this.blobToBuffer(file));
445
439
  return this.prepareSongBlobFile(buffer, file);
446
440
  }
447
441
 
448
- if(Buffer.isBuffer(file)) {
442
+ if (Buffer.isBuffer(file)) {
449
443
  return NodeID3.write(tags, file);
450
444
  }
451
445
 
452
446
  return new Promise((resolve, reject) => {
453
447
  NodeID3.write(tags, file.path || file, (err) => {
454
- if(err) {
448
+ if (err) {
455
449
  return reject(err);
456
450
  }
457
451
 
458
- if(file.path) {
452
+ if (file.path) {
459
453
  file.destroy();
460
- file = fs.createReadStream(file.path);
454
+ file = fse.createReadStream(file.path);
461
455
  }
462
-
463
456
  resolve(file);
464
457
  });
465
458
  });
@@ -467,167 +460,165 @@ utils.setSongTags = async function (file, tags) {
467
460
 
468
461
  /**
469
462
  * Add the song tags
470
- *
463
+ *
471
464
  * @async
472
- * @param {string|Buffer|fs.ReadStream|Blob} file
465
+ * @param {string|Buffer|fse.ReadStream|Blob} file
473
466
  * @param {object} tags
474
- * @returns {string|Buffer|fs.ReadStream|Blob}
467
+ * @returns {string|Buffer|fse.ReadStream|Blob}
475
468
  */
476
469
  utils.addSongTags = async function (file, tags) {
477
470
  tags = await this.prepareSongTagsToSet(tags);
478
-
479
- if(typeof Blob == 'function' && file instanceof Blob) {
471
+
472
+ if (typeof Blob == 'function' && file instanceof Blob) {
480
473
  const buffer = NodeID3.update(tags, await this.blobToBuffer(file));
481
474
  return this.prepareSongBlobFile(buffer, file);
482
475
  }
483
476
 
484
- if(Buffer.isBuffer(file)) {
477
+ if (Buffer.isBuffer(file)) {
485
478
  return NodeID3.update(tags, file);
486
479
  }
487
480
 
488
481
  return new Promise((resolve, reject) => {
489
482
  NodeID3.update(tags, file.path || file, (err) => {
490
- if(err) {
483
+ if (err) {
491
484
  return reject(err);
492
485
  }
493
486
 
494
- if(file.path) {
487
+ if (file.path) {
495
488
  file.destroy();
496
- file = fs.createReadStream(file.path);
489
+ file = fse.createReadStream(file.path);
497
490
  }
498
491
 
499
492
  resolve(file);
500
493
  });
501
- });
494
+ });
502
495
  };
503
496
 
504
497
  /**
505
498
  * Remove the song
506
- *
499
+ *
507
500
  * @async
508
- * @param {string|Buffer|fs.ReadStream|Blob} file
509
- * @returns {string|Buffer|fs.ReadStream|Blob}
501
+ * @param {string|Buffer|fse.ReadStream|Blob} file
502
+ * @returns {string|Buffer|fse.ReadStream|Blob}
510
503
  */
511
504
  utils.removeSongTags = async function (file) {
512
- if(typeof Blob == 'function' && file instanceof Blob) {
505
+ if (typeof Blob == 'function' && file instanceof Blob) {
513
506
  const buffer = NodeID3.removeTagsFromBuffer(await this.blobToBuffer(file));
514
507
  return this.prepareSongBlobFile(buffer, file);
515
508
  }
516
509
 
517
- if(Buffer.isBuffer(file)) {
510
+ if (Buffer.isBuffer(file)) {
518
511
  return NodeID3.removeTagsFromBuffer(file);
519
512
  }
520
513
 
521
514
  return new Promise((resolve, reject) => {
522
515
  NodeID3.removeTags(file.path || file, (err) => {
523
- if(err) {
516
+ if (err) {
524
517
  return reject(err);
525
518
  }
526
519
 
527
- if(file.path) {
520
+ if (file.path) {
528
521
  file.destroy();
529
- file = fs.createReadStream(file.path);
522
+ file = fse.createReadStream(file.path);
530
523
  }
531
-
532
524
  resolve(file);
533
525
  });
534
- });
526
+ });
535
527
  };
536
528
 
537
529
  /**
538
530
  * Get the song metadata
539
- *
531
+ *
540
532
  * @async
541
- * @param {string|Buffer|fs.ReadStream|Blob} file
542
- * @returns {object}
533
+ * @param {string|Buffer|fse.ReadStream|Blob} file
534
+ * @returns {object}
543
535
  */
544
536
  utils.getSongMetadata = async function (file) {
545
- if(typeof Blob == 'function' && file instanceof Blob) {
546
- file= await this.blobToBuffer(file);
537
+ if (typeof Blob == 'function' && file instanceof Blob) {
538
+ file = await this.blobToBuffer(file);
547
539
  }
548
540
 
549
- if(utils.isFileReadStream(file)) {
541
+ if (utils.isFileReadStream(file)) {
550
542
  file = file.path;
551
543
  }
552
-
553
- const data = await mm[typeof file == 'string'? 'parseFile': 'parseBuffer'](file, { duration: true });
544
+
545
+ const data = await mm[typeof file == 'string' ? 'parseFile' : 'parseBuffer'](file, { duration: true });
554
546
  return data.format;
555
547
  };
556
548
 
557
549
  /**
558
550
  * Encode the song title
559
- *
551
+ *
560
552
  * @param {string} title
561
553
  * @returns {string}
562
554
  */
563
555
  utils.encodeSongTitle = function (title) {
564
556
  return base64url(title);
565
- }
557
+ };
566
558
 
567
559
  /**
568
560
  * Decode the song title
569
- *
561
+ *
570
562
  * @param {string} title
571
563
  * @returns {string}
572
564
  */
573
565
  utils.decodeSongTitle = function (title) {
574
566
  return base64url.decode(title);
575
- }
567
+ };
576
568
 
577
569
  /**
578
570
  * Check the value is a valid song priority
579
- *
571
+ *
580
572
  * @param {*} title
581
573
  * @returns {boolean}
582
574
  */
583
575
  utils.isValidSongPriority = function (value) {
584
576
  return [0, 1, -1].includes(value);
585
- }
577
+ };
586
578
 
587
579
  /**
588
580
  * Calculate two strings similarity
589
- *
581
+ *
590
582
  * @param {string} first
591
583
  * @param {string} second
592
584
  * @param {object} [options]
593
585
  * @param {number} [options.min]
594
586
  * @param {boolean} [options.ignoreOrder]
595
- *
596
- * @returns {number}
587
+ *
588
+ * @returns {number}
597
589
  */
598
- utils.getStringSimilarity = function(first, second, options = {}) {
599
- const min = options.min || 0;
590
+ utils.getStringSimilarity = function (first, second, options = {}) {
591
+ const min = options.min || 0;
600
592
  let short = first;
601
593
  let long = second;
602
594
 
603
- if(second.length < first.length) {
595
+ if (second.length < first.length) {
604
596
  short = second;
605
597
  long = first;
606
598
  }
607
-
599
+
608
600
  long = long.toLowerCase().split('');
609
601
  short = short.toLowerCase().split('');
610
602
  const coef = Math.sqrt(short.length * long.length);
611
603
  let matches = 0;
612
604
 
613
- for(let i = 0; i < short.length; i++) {
605
+ for (let i = 0; i < short.length; i++) {
614
606
  let index = -1;
615
607
  let dist = 0;
616
608
 
617
- while(dist < long.length) {
618
- if(long[i + dist] === short[i]) {
609
+ while (dist < long.length) {
610
+ if (long[i + dist] === short[i]) {
619
611
  index = i + dist;
620
612
  break;
621
613
  }
622
- else if(long[i - dist] === short[i]) {
614
+ else if (long[i - dist] === short[i]) {
623
615
  index = i - dist;
624
616
  break;
625
617
  }
626
-
627
618
  dist++;
628
619
  }
629
620
 
630
- if(index != -1) {
621
+ if (index != -1) {
631
622
  let coef = 1;
632
623
  !options.ignoreOrder && (coef = 1 - Math.abs(index - i) / short.length);
633
624
  matches += coef;
@@ -636,36 +627,36 @@ utils.getStringSimilarity = function(first, second, options = {}) {
636
627
 
637
628
  const res = short.length + matches - i - 1;
638
629
 
639
- if(res / coef < min) {
630
+ if (res / coef < min) {
640
631
  return 0;
641
632
  }
642
633
  }
643
634
 
644
635
  return matches / coef;
645
- }
636
+ };
646
637
 
647
638
  /**
648
639
  * Normalize the string
649
- *
640
+ *
650
641
  * @param {string} str
651
642
  * @returns {string}
652
643
  */
653
644
  utils.normalizeString = function (str) {
654
645
  return str.normalize("NFD").replace(/(?!\^)\p{Diacritic}/gu, "");
655
- }
646
+ };
656
647
 
657
648
  /**
658
649
  * Stringfy numbers in the string
659
- *
650
+ *
660
651
  * @param {string} str
661
652
  * @returns {string}
662
653
  */
663
654
  utils.stringifyNumbers = function (str) {
664
655
  const arr = [
665
- 'zero', 'one', 'two', 'three', 'four',
656
+ 'zero', 'one', 'two', 'three', 'four',
666
657
  'five', 'six', 'seven', 'eight', 'nine'
667
658
  ];
668
659
  return str.replace(/[0-9]{1}/g, m => arr[+m]);
669
- }
660
+ };
670
661
 
671
- module.exports = utils;
662
+ export default utils;