alchemymvc 1.3.15 → 1.3.17

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/lib/core/base.js CHANGED
@@ -35,7 +35,7 @@ __Protoblast.getGroup = function getGroup(name) {
35
35
  *
36
36
  * @author Jelle De Loecker <jelle@develry.be>
37
37
  * @since 0.3.0
38
- * @version 1.2.6
38
+ * @version 1.3.17
39
39
  */
40
40
  Base.constitute(function setBasicBehaviour() {
41
41
 
@@ -134,6 +134,28 @@ Base.constitute(function setBasicBehaviour() {
134
134
  this.setStatic('title', this.createClassTitle(name), false);
135
135
  }
136
136
 
137
+ // And also set the type path
138
+ if (!this.hasOwnProperty('type_path')) {
139
+ let namespace = this.namespace;
140
+ let parent_namespace = this.super?.namespace;
141
+ let type_path = this.type_name;
142
+
143
+ // Add extra identifier info if this child comes from another namespace
144
+ if (namespace && namespace != parent_namespace) {
145
+ if (parent_namespace && namespace.startsWith(parent_namespace)) {
146
+ namespace = namespace.after(parent_namespace);
147
+
148
+ if (namespace[0] == '.') {
149
+ namespace = namespace.slice(1);
150
+ }
151
+ }
152
+
153
+ type_path = Blast.Bound.String.underscore(Blast.Bound.String.slug(namespace)) + '.' + type_path;
154
+ }
155
+
156
+ this.setStatic('type_path', type_path, false);
157
+ }
158
+
137
159
  // Add this class to the shared group
138
160
  shared_group[this.type_name] = this;
139
161
  });
@@ -315,11 +315,11 @@ Alchemy.setMethod(function castObjectId(str) {
315
315
  /**
316
316
  * Is the given parameter an object id (string or instance)
317
317
  *
318
- * @author Jelle De Loecker <jelle@develry.be>
318
+ * @author Jelle De Loecker <jelle@elevenways.be>
319
319
  * @since 1.0.4
320
- * @version 1.0.5
320
+ * @version 1.3.16
321
321
  *
322
- * @param {String|ObjectID} obj
322
+ * @param {String|ObjectId} obj
323
323
  *
324
324
  * @return {Boolean}
325
325
  */
@@ -331,9 +331,13 @@ Alchemy.setMethod(function isObjectId(obj) {
331
331
 
332
332
  let type = typeof obj;
333
333
 
334
- if (obj && type === 'object' && obj.constructor && obj.constructor.name === 'ObjectID') {
334
+ if (type === 'string' && obj.isObjectId()) {
335
335
  return true;
336
- } else if (type === 'string' && obj.isObjectId()) {
336
+ }
337
+
338
+ let class_name = obj.constructor?.name;
339
+
340
+ if (class_name == 'ObjectID' || class_name == 'ObjectId') {
337
341
  return true;
338
342
  }
339
343
 
@@ -311,7 +311,7 @@ Alchemy.setMethod(function sourcemapMiddleware(req, res, nextMiddleware) {
311
311
  *
312
312
  * @author Jelle De Loecker <jelle@develry.be>
313
313
  * @since 0.2.0
314
- * @version 1.3.4
314
+ * @version 1.3.17
315
315
  *
316
316
  * @param {String} path
317
317
  * @param {Object} options
@@ -418,7 +418,7 @@ Alchemy.setMethod(function minifyScript(path, options, callback) {
418
418
  }
419
419
  }
420
420
 
421
- if (should_minify) {
421
+ if (should_minify && typeof Terser?.minify == 'function') {
422
422
 
423
423
  // Force Blast.isNode & Blast.isBrowser to be replaced later
424
424
  data = data.replaceAll('Blast.isNode', '__BLAST_IS_NODE');
@@ -135,7 +135,11 @@ global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
135
135
  this.startJaneway();
136
136
  }
137
137
  } catch (err) {
138
- log.warn('Failed to start Janeway:', err);
138
+ if (typeof log != 'undefined') {
139
+ log.warn('Failed to start Janeway:', err);
140
+ } else {
141
+ console.warn('Failed to start Janeway:', err);
142
+ }
139
143
  }
140
144
  });
141
145
 
@@ -357,6 +361,61 @@ Alchemy.setMethod(function isTooBusyForAjax() {
357
361
  return false;
358
362
  });
359
363
 
364
+ /**
365
+ * Called after the server has started
366
+ *
367
+ * @author Jelle De Loecker <jelle@elevenways.be>
368
+ * @since 1.3.17
369
+ * @version 1.3.17
370
+ */
371
+ Alchemy.setMethod(function afterStart() {
372
+ this.startTaskService();
373
+ });
374
+
375
+ let task_service_has_started = false;
376
+
377
+ /**
378
+ * Start the task service
379
+ *
380
+ * @author Jelle De Loecker <jelle@elevenways.be>
381
+ * @since 1.3.17
382
+ * @version 1.3.17
383
+ */
384
+ Alchemy.setMethod(function startTaskService() {
385
+
386
+ if (task_service_has_started) {
387
+ return;
388
+ }
389
+
390
+ task_service_has_started = true;
391
+
392
+ this.task_service = new Classes.Alchemy.Task.TaskService();
393
+ });
394
+
395
+ /**
396
+ * Is the given PID running?
397
+ *
398
+ * @author Jelle De Loecker <jelle@elevenways.be>
399
+ * @since 1.3.17
400
+ * @version 1.3.17
401
+ *
402
+ * @param {Number} pid
403
+ *
404
+ * @return {Boolean}
405
+ */
406
+ Alchemy.setMethod(function isProcessRunning(pid) {
407
+
408
+ if (!pid) {
409
+ return false;
410
+ }
411
+
412
+ try {
413
+ return process.kill(pid, 0);
414
+ } catch (e) {
415
+ return e.code === 'EPERM'
416
+ }
417
+ });
418
+
360
419
  /**
361
420
  * Start janeway
362
421
  *
@@ -441,6 +500,13 @@ Alchemy.setMethod(function startJaneway(options) {
441
500
  return session_menu.remove();
442
501
  }
443
502
 
503
+ session_menu.addItem({
504
+ title : 'Current active browser sessions:',
505
+ weight : Infinity,
506
+ }, () => {
507
+ console.log('All sessions:', alchemy.sessions);
508
+ });
509
+
444
510
  this.Janeway.session_menu = session_menu;
445
511
  }
446
512
 
@@ -1051,7 +1117,7 @@ Alchemy.setMethod(function searchModule(startPath, moduleName, recurse) {
1051
1117
  *
1052
1118
  * @author Jelle De Loecker <jelle@develry.be>
1053
1119
  * @since 0.0.1
1054
- * @version 1.2.7
1120
+ * @version 1.3.17
1055
1121
  *
1056
1122
  * @param {String} moduleName
1057
1123
  * @param {Object} options
@@ -1177,7 +1243,32 @@ Alchemy.setMethod(function findModule(moduleName, options) {
1177
1243
 
1178
1244
  // Modules are required by default
1179
1245
  if (options.require) {
1180
- if (package_json && package_json.type == 'module' && !(package_json.main && package_json.module)) {
1246
+
1247
+ let supports_cjs = package_json?.type != 'module';
1248
+
1249
+ // Make sure this does not support CJS.
1250
+ // Some packages have the `module` type, but do have CJS exports too
1251
+ if (!supports_cjs) {
1252
+
1253
+ if (package_json.module && package_json.main) {
1254
+ supports_cjs = true;
1255
+ } else {
1256
+
1257
+ let exports = package_json.exports?.['.'];
1258
+
1259
+ if (Array.isArray(exports)) {
1260
+ for (let entry of exports) {
1261
+ if (entry && typeof entry == 'object' && entry.require) {
1262
+ supports_cjs = true;
1263
+ }
1264
+ }
1265
+ } else if (exports?.require) {
1266
+ supports_cjs = true;
1267
+ }
1268
+ }
1269
+ }
1270
+
1271
+ if (!supports_cjs) {
1181
1272
  module = doImport(module_path)
1182
1273
  } else {
1183
1274
  module = require(module_path);
@@ -1248,22 +1339,28 @@ Alchemy.setMethod(function shared(name, type, value) {
1248
1339
  *
1249
1340
  * @author Jelle De Loecker <jelle@develry.be>
1250
1341
  * @since 0.0.1
1251
- * @version 0.4.0
1342
+ * @version 1.3.16
1252
1343
  *
1253
- * @param {String|ObjectID} obj
1344
+ * @param {String|ObjectId} obj
1254
1345
  *
1255
- * @return {ObjectID|undefined}
1346
+ * @return {ObjectId|undefined}
1256
1347
  */
1257
1348
  Alchemy.setMethod(function castObjectId(obj) {
1258
1349
 
1259
- var type = typeof obj;
1350
+ let type = typeof obj;
1260
1351
 
1261
- if (obj && type === 'object' && obj.constructor && obj.constructor.name === 'ObjectID') {
1262
- return obj;
1263
- } else if (type === 'string' && obj.isObjectId()) {
1352
+ if (type === 'string' && obj.isObjectId()) {
1264
1353
  return alchemy.ObjectId(obj);
1265
1354
  }
1266
1355
 
1356
+ if (obj && type === 'object') {
1357
+ let class_name = obj.constructor?.name;
1358
+
1359
+ if (class_name == 'ObjectID' || class_name == 'ObjectId') {
1360
+ return obj;
1361
+ }
1362
+ }
1363
+
1267
1364
  return undefined;
1268
1365
  });
1269
1366
 
@@ -1595,6 +1692,12 @@ Alchemy.setMethod(function parseRequestBody(req, res, callback) {
1595
1692
  return callback(null);
1596
1693
  }
1597
1694
 
1695
+ // Since formidable v3, all the fields are now arrays.
1696
+ // We already had a lot of logic to deal with this,
1697
+ // so we just have to un-array everything
1698
+ form_fields = undoFormidableArray(form_fields);
1699
+ form_files = undoFormidableArray(form_files);
1700
+
1598
1701
  // Fix the field names
1599
1702
  for (key in form_fields) {
1600
1703
  Object.setFormPath(fields, key, form_fields[key]);
@@ -1679,6 +1782,42 @@ Alchemy.setMethod(function parseRequestBody(req, res, callback) {
1679
1782
  });
1680
1783
  });
1681
1784
 
1785
+ /**
1786
+ * Undo formidable's new array handling
1787
+ *
1788
+ * @author Jelle De Loecker <jelle@elevenways.be>
1789
+ * @since 1.3.16
1790
+ * @version 1.3.16
1791
+ *
1792
+ * @param {Object}
1793
+ *
1794
+ * @return {Object}
1795
+ */
1796
+ function undoFormidableArray(data) {
1797
+
1798
+ if (!data) {
1799
+ return {};
1800
+ }
1801
+
1802
+ let result = {},
1803
+ value,
1804
+ key;
1805
+
1806
+ for (key in data) {
1807
+ value = data[key];
1808
+
1809
+ if (key.endsWith('[]')) {
1810
+ key = key.slice(0, -2);
1811
+ } else {
1812
+ value = value[0];
1813
+ }
1814
+
1815
+ result[key] = value;
1816
+ }
1817
+
1818
+ return result;
1819
+ }
1820
+
1682
1821
  /**
1683
1822
  * Export all data
1684
1823
  *
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var mkdirp = alchemy.use('mkdirp'),
3
+ let mkdirp = alchemy.use('mkdirp')?.mkdirp,
4
4
  ncp = alchemy.use('ncp').ncp,
5
5
  fs = alchemy.use('fs'),
6
6
  libpath = alchemy.use('path'),
@@ -496,6 +496,7 @@ Alchemy.setMethod(function getShared(first, second) {
496
496
 
497
497
  /**
498
498
  * Make JSON-Dry handle ObjectIDs when drying
499
+ * (Old class name)
499
500
  *
500
501
  * @author Jelle De Loecker <jelle@develry.be>
501
502
  * @since 0.2.0
@@ -507,16 +508,65 @@ JSON.registerDrier('ObjectID', function dryOI(holder, key, value) {
507
508
 
508
509
  /**
509
510
  * Correctly un-dry ObjectIDs
511
+ * (Old class name)
510
512
  *
511
513
  * @author Jelle De Loecker <jelle@develry.be>
512
514
  * @since 0.2.0
513
515
  * @version 0.2.0
514
516
  */
515
517
  JSON.registerUndrier('ObjectID', function undryOI(holder, key, value) {
516
- return mongo.ObjectID(value);
518
+ return alchemy.castObjectId(value);
517
519
  });
518
520
 
519
- alchemy.ObjectId = mongo.ObjectID;
521
+ /**
522
+ * Make JSON-Dry handle ObjectIds when drying
523
+ *
524
+ * @author Jelle De Loecker <jelle@elevenways.be>
525
+ * @since 1.3.16
526
+ * @version 1.3.16
527
+ */
528
+ JSON.registerDrier('ObjectId', function dryOI(holder, key, value) {
529
+ return ''+value;
530
+ }, {add_path: false});
531
+
532
+ /**
533
+ * Correctly un-dry ObjectIds
534
+ *
535
+ * @author Jelle De Loecker <jelle@elevenways.be>
536
+ * @since 1.3.16
537
+ * @version 1.3.16
538
+ */
539
+ JSON.registerUndrier('ObjectId', function undryOI(holder, key, value) {
540
+ return alchemy.castObjectId(value);
541
+ });
542
+
543
+ /**
544
+ * Monkey-patch checksum support to the ObjectId class
545
+ *
546
+ * @author Jelle De Loecker <jelle@elevenways.be>
547
+ * @since 1.3.16
548
+ * @version 1.3.16
549
+ */
550
+ if (typeof mongo?.ObjectId == 'function') {
551
+ Function.setMethod(mongo.ObjectId, Blast.checksumSymbol, function checksum() {
552
+ return this.toString();
553
+ });
554
+ }
555
+
556
+ /**
557
+ * Create a new ObjectId
558
+ *
559
+ * @author Jelle De Loecker <jelle@elevenways.be>
560
+ * @since 1.3.16
561
+ * @version 1.3.16
562
+ *
563
+ * @param {*} object_id
564
+ *
565
+ * @return {ObjectId}
566
+ */
567
+ Alchemy.setMethod(function ObjectId(object_id) {
568
+ return new mongo.ObjectId(object_id);
569
+ });
520
570
 
521
571
  /**
522
572
  * Get mimetype info of a file
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alchemymvc",
3
3
  "description": "MVC framework for Node.js",
4
- "version": "1.3.15",
4
+ "version": "1.3.17",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -14,29 +14,29 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "ansi-256-colors" : "~1.1.0",
17
- "autoprefixer" : "~10.4.2",
18
- "bcrypt" : "~5.0.1",
17
+ "autoprefixer" : "~10.4.16",
18
+ "bcrypt" : "~5.1.1",
19
19
  "body" : "~5.1.0",
20
- "body-parser" : "~1.19.2",
21
- "bson" : "~4.6.1",
20
+ "body-parser" : "~1.20.2",
21
+ "bson" : "~6.1.0",
22
22
  "chokidar" : "~3.5.3",
23
- "formidable" : "~2.1.1",
24
- "graceful-fs" : "~4.2.9",
25
- "hawkejs" : "~2.3.9",
26
- "jsondiffpatch" : "~0.4.1",
23
+ "formidable" : "~3.5.1",
24
+ "graceful-fs" : "~4.2.11",
25
+ "hawkejs" : "~2.3.13",
26
+ "jsondiffpatch" : "~0.5.0",
27
27
  "mime" : "~3.0.0",
28
28
  "minimist" : "~1.2.5",
29
- "mkdirp" : "~1.0.4",
29
+ "mkdirp" : "~3.0.1",
30
30
  "mmmagic" : "~0.5.3",
31
- "mongodb" : "~3.6.6",
31
+ "mongodb" : "~6.1.0",
32
32
  "ncp" : "~2.0.0",
33
- "postcss" : "~8.4.6",
34
- "protoblast" : "~0.8.9",
35
- "semver" : "~7.3.5",
36
- "socket.io" : "~4.6.0",
33
+ "postcss" : "~8.4.31",
34
+ "protoblast" : "~0.8.12",
35
+ "semver" : "~7.5.4",
36
+ "socket.io" : "~4.7.2",
37
37
  "@11ways/socket.io-stream" : "~0.9.2",
38
38
  "sputnik" : "~0.1.0",
39
- "terser" : "~5.18.1",
39
+ "terser" : "~5.21.0",
40
40
  "toobusy-js" : "~0.5.1",
41
41
  "useragent" : "~2.3.0"
42
42
  },
@@ -45,21 +45,21 @@
45
45
  "index.js"
46
46
  ],
47
47
  "optionalDependencies": {
48
- "janeway" : "~0.4.0",
49
- "less" : "~4.1.1",
50
- "sass" : "~1.53.0",
51
- "sass-embedded" : "~1.53.0",
48
+ "janeway" : "~0.4.2",
49
+ "less" : "~4.2.0",
50
+ "sass" : "~1.68.0",
51
+ "sass-embedded" : "~1.67.0",
52
52
  "nodent-compiler" : "~3.2.13",
53
- "socket.io-client" : "~4.6.0",
53
+ "socket.io-client" : "~4.7.2",
54
54
  "socket.io-msgpack-parser": "~3.0.2"
55
55
  },
56
56
  "devDependencies": {
57
57
  "codecov" : "~3.8.1",
58
- "istanbul-lib-instrument" : "~4.0.3",
58
+ "istanbul-lib-instrument" : "~6.0.1",
59
59
  "mocha" : "~10.2.0",
60
- "mongo-unit" : "~3.2.0",
60
+ "mongo-unit" : "~3.3.0",
61
61
  "nyc" : "^15.1.0",
62
- "puppeteer" : "~19.0.0",
62
+ "puppeteer" : "~21.3.6",
63
63
  "source-map" : "~0.7.3"
64
64
  },
65
65
  "scripts": {
@@ -71,6 +71,6 @@
71
71
  "main": "lib/bootstrap.js",
72
72
  "license": "MIT",
73
73
  "engines": {
74
- "node" : ">=14.0.0"
74
+ "node" : ">=16.20.1"
75
75
  }
76
76
  }