apostrophe 3.53.0 → 3.55.0

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 (77) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/defaults.js +1 -0
  3. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextModeAndSettings.vue +5 -2
  4. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +28 -19
  5. package/modules/@apostrophecms/any-doc-type/index.js +2 -2
  6. package/modules/@apostrophecms/any-page-type/index.js +2 -2
  7. package/modules/@apostrophecms/doc/index.js +55 -29
  8. package/modules/@apostrophecms/doc-type/index.js +11 -6
  9. package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocContextMenu.vue +4 -440
  10. package/modules/@apostrophecms/doc-type/ui/apos/logic/AposDocContextMenu.js +445 -0
  11. package/modules/@apostrophecms/i18n/i18n/de.json +113 -105
  12. package/modules/@apostrophecms/i18n/i18n/es.json +10 -0
  13. package/modules/@apostrophecms/i18n/i18n/fr.json +8 -0
  14. package/modules/@apostrophecms/i18n/i18n/pt-BR.json +10 -0
  15. package/modules/@apostrophecms/i18n/i18n/sk.json +8 -0
  16. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +1 -0
  17. package/modules/@apostrophecms/log/index.js +429 -0
  18. package/modules/@apostrophecms/login/index.js +47 -4
  19. package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +14 -1
  20. package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +1 -1
  21. package/modules/@apostrophecms/module/index.js +32 -6
  22. package/modules/@apostrophecms/module/lib/log.js +68 -0
  23. package/modules/@apostrophecms/page/index.js +71 -19
  24. package/modules/@apostrophecms/page/lib/legacy-migrations.js +0 -57
  25. package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +8 -285
  26. package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +291 -0
  27. package/modules/@apostrophecms/page-type/index.js +39 -26
  28. package/modules/@apostrophecms/piece-type/index.js +19 -11
  29. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +1 -0
  30. package/modules/@apostrophecms/schema/ui/apos/components/AposArrayEditor.vue +2 -357
  31. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArea.vue +2 -86
  32. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +2 -254
  33. package/modules/@apostrophecms/schema/ui/apos/components/AposInputAttachment.vue +2 -77
  34. package/modules/@apostrophecms/schema/ui/apos/components/AposInputBoolean.vue +2 -44
  35. package/modules/@apostrophecms/schema/ui/apos/components/AposInputCheckboxes.vue +2 -64
  36. package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +2 -94
  37. package/modules/@apostrophecms/schema/ui/apos/components/AposInputDateAndTime.vue +3 -47
  38. package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +2 -82
  39. package/modules/@apostrophecms/schema/ui/apos/components/AposInputPassword.vue +2 -37
  40. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRadio.vue +2 -26
  41. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRange.vue +2 -57
  42. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRelationship.vue +2 -259
  43. package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +2 -38
  44. package/modules/@apostrophecms/schema/ui/apos/components/AposInputSlug.vue +2 -275
  45. package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +2 -167
  46. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +2 -115
  47. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +3 -279
  48. package/modules/@apostrophecms/schema/ui/apos/components/AposSearchList.vue +2 -83
  49. package/modules/@apostrophecms/schema/ui/apos/lib/detectChange.js +10 -1
  50. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +361 -0
  51. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +89 -0
  52. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +257 -0
  53. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputAttachment.js +81 -0
  54. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputBoolean.js +48 -0
  55. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputCheckboxes.js +68 -0
  56. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputColor.js +98 -0
  57. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputDateAndTime.js +49 -0
  58. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +86 -0
  59. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputPassword.js +41 -0
  60. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRadio.js +29 -0
  61. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRange.js +60 -0
  62. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputRelationship.js +262 -0
  63. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSelect.js +41 -0
  64. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSlug.js +278 -0
  65. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputString.js +170 -0
  66. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputWrapper.js +118 -0
  67. package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +281 -0
  68. package/modules/@apostrophecms/schema/ui/apos/logic/AposSearchList.js +85 -0
  69. package/modules/@apostrophecms/template/index.js +1 -1
  70. package/modules/@apostrophecms/ui/ui/apos/components/AposTreeHeader.vue +2 -2
  71. package/modules/@apostrophecms/util/index.js +83 -13
  72. package/modules/@apostrophecms/util/lib/logger.js +19 -17
  73. package/package.json +1 -1
  74. package/test/docs.js +35 -2
  75. package/test/log.js +1765 -0
  76. package/test/pages.js +57 -0
  77. package/test-lib/util.js +1 -1
@@ -5,7 +5,7 @@
5
5
 
6
6
  // ## Options
7
7
  //
8
- // ### `logger`
8
+ // ### `logger` (LEGACY)
9
9
  //
10
10
  // A function which accepts `apos` and returns an object with
11
11
  // at least `info`, `debug`, `warn` and `error` methods. These methods should
@@ -16,6 +16,11 @@
16
16
  // `apos.util.error`, etc. are routed through this object
17
17
  // by Apostrophe. This provides compatibility out of
18
18
  // the box with many popular logging modules, including `winston`.
19
+ // NOTE: this option is deprecated, you should configure `@apostrophecms/log`
20
+ // module instead. This option will still work for BC reasons, but switching
21
+ // to structured logging and module `self.logInfo()`, `self.logError()`, etc
22
+ // is highly recommended.
23
+ // Read more in the`@apostrophecms/log` module documentation.
19
24
 
20
25
  const _ = require('lodash');
21
26
  const he = require('he');
@@ -46,6 +51,17 @@ module.exports = {
46
51
  self.warnedDev = {};
47
52
  return self.enableLogger();
48
53
  },
54
+ handlers(self) {
55
+ return {
56
+ 'apostrophe:destroy': {
57
+ async destroyLogger() {
58
+ if (self.logger.destroy) {
59
+ await self.logger.destroy();
60
+ }
61
+ }
62
+ }
63
+ };
64
+ },
49
65
  methods(self) {
50
66
  return {
51
67
  // generate a unique identifier for a new page or other object.
@@ -504,7 +520,20 @@ module.exports = {
504
520
  }
505
521
  },
506
522
  enableLogger() {
507
- self.logger = self.options.logger ? self.options.logger(self.apos) : require('./lib/logger.js')(self.apos);
523
+ // Legacy, configured via this module.
524
+ if (self.options.logger) {
525
+ self.logger = self.options.logger(self.apos);
526
+ return;
527
+ }
528
+ // New, configured via the `log` module.
529
+ const logOpts = self.apos.structuredLog.options;
530
+ if (logOpts.logger) {
531
+ self.logger = typeof logOpts.logger === 'function'
532
+ ? logOpts.logger(self.apos)
533
+ : logOpts.logger;
534
+ return;
535
+ }
536
+ self.logger = require('./lib/logger.js')(self.apos);
508
537
  },
509
538
  // Log a message. The default
510
539
  // implementation wraps `console.log` and passes on
@@ -517,11 +546,12 @@ module.exports = {
517
546
  // If the logger has no `log` method, the `info` method
518
547
  // is used. This allows an instance of `bole` or similar
519
548
  // to be used directly.
520
- log(msg) {
549
+ log(...args) {
550
+ // kept for bc
521
551
  if (!self.logger.log) {
522
- return self.logger.info.apply(self.logger.info, arguments);
552
+ return self.logger.info(...self.convertLegacyLogPayload(args));
523
553
  }
524
- self.logger.log.apply(self.logger, arguments);
554
+ self.logger.log(...self.convertLegacyLogPayload(args));
525
555
  },
526
556
  // Log an informational message. The default
527
557
  // implementation wraps `console.info` and passes on
@@ -530,8 +560,8 @@ module.exports = {
530
560
  // Overrides should be written with support for
531
561
  // substitution strings in mind. See the
532
562
  // `console.log` documentation.
533
- info(msg) {
534
- self.logger.info.apply(self.logger, arguments);
563
+ info(...args) {
564
+ self.logger.info(...self.convertLegacyLogPayload(args));
535
565
  },
536
566
  // Log a debug message. The default implementation wraps
537
567
  // `console.debug` if available, otherwise `console.log`,
@@ -540,8 +570,8 @@ module.exports = {
540
570
  // Overrides should be written with support for
541
571
  // substitution strings in mind. See the
542
572
  // `console.warn` documentation.
543
- debug(msg) {
544
- self.logger.debug.apply(self.logger, arguments);
573
+ debug(...args) {
574
+ self.logger.debug(...self.convertLegacyLogPayload(args));
545
575
  },
546
576
  // Log a warning. The default implementation wraps
547
577
  // `console.warn` and passes on all arguments,
@@ -554,8 +584,8 @@ module.exports = {
554
584
  // The intention is that `apos.util.warn` should be
555
585
  // called for situations less dire than
556
586
  // `apos.util.error`.
557
- warn(msg) {
558
- self.logger.warn.apply(self.logger, arguments);
587
+ warn(...args) {
588
+ self.logger.warn(...self.convertLegacyLogPayload(args));
559
589
  },
560
590
 
561
591
  // Identical to `apos.util.warn`, except that the warning is
@@ -605,8 +635,8 @@ module.exports = {
605
635
  // Overrides should be written with support for
606
636
  // substitution strings in mind. See the
607
637
  // `console.error` documentation.
608
- error(msg) {
609
- self.logger.error.apply(self.logger, arguments);
638
+ error(...args) {
639
+ self.logger.error(...self.convertLegacyLogPayload(args));
610
640
  },
611
641
  // Performance profiling method. At the start of the operation you want
612
642
  // to profile, call with req (may be null or omitted entirely) and a
@@ -811,6 +841,46 @@ module.exports = {
811
841
  },
812
842
  omit(source, keys) {
813
843
  return _.omit(source, keys);
844
+ },
845
+
846
+ // Internal method. Attempt to convert the log payload to an object
847
+ // for legacy calls and when `@apostrophecms/log` has been configured
848
+ // with `messageAs: 'someKey'`.
849
+ // This change is backwards compatible with the previous behavior because
850
+ // `messageAs` is a newly introduced option. Custom loggers should adapt
851
+ // to this change when using `messageAs`.
852
+ // `args` is the argument array passed to the any log method.
853
+ // The result (when required) is an array with a single object.
854
+ // First string argument (if available) is used as `message`.
855
+ // First object argument is used as result object.
856
+ // All other arguments are passed as `args` property of the result object.
857
+ convertLegacyLogPayload(args) {
858
+ const messageAs = self.apos.structuredLog.options.messageAs;
859
+ if (!messageAs || args.length === 0) {
860
+ return args;
861
+ }
862
+ // Already formatted by the structured log module. Nothing we can do if not.
863
+ if (args.length === 1 && _.isPlainObject(args[0])) {
864
+ return args;
865
+ }
866
+
867
+ // Should also handle apos.util.warnDev() calls.
868
+ const messageIndex = args
869
+ .findIndex(arg => typeof arg === 'string' && arg.trim() && arg !== '\n⚠️ ');
870
+ const firstObjectIndex = args.findIndex(arg => _.isPlainObject(arg));
871
+ const message = messageIndex !== -1 ? args[messageIndex] : null;
872
+ const firstObject = firstObjectIndex !== -1 ? { ...args[firstObjectIndex] } : {};
873
+
874
+ if (message) {
875
+ firstObject[messageAs] = message;
876
+ }
877
+ const rest = args
878
+ .filter((arg, index) => ![ messageIndex, firstObjectIndex ].includes(index));
879
+ if (rest.length) {
880
+ firstObject.args = rest;
881
+ }
882
+
883
+ return [ firstObject ];
814
884
  }
815
885
  };
816
886
  },
@@ -1,7 +1,9 @@
1
1
  // Default logger. You may pass an alternate implementation
2
2
  // as the `logger` top-level option when configuring Apostrophe.
3
3
 
4
- module.exports = function(apos) {
4
+ module.exports = function (apos) {
5
+ const logModule = apos.structuredLog;
6
+
5
7
  return {
6
8
  // Log a message. The default
7
9
  // implementation wraps `console.log` and passes on
@@ -11,9 +13,9 @@ module.exports = function(apos) {
11
13
  // substitution strings in mind. See the
12
14
  // `console.log` documentation.
13
15
 
14
- log: function(msg) {
16
+ log: function(...args) {
15
17
  // eslint-disable-next-line no-console
16
- console.log.apply(console, arguments);
18
+ console.log(...logModule.formatLogByEnv(args));
17
19
  },
18
20
 
19
21
  // Log an informational message.
@@ -22,9 +24,9 @@ module.exports = function(apos) {
22
24
  // substitution strings in mind. See the
23
25
  // `console.log` documentation.
24
26
 
25
- info: function(msg) {
27
+ info: function(...args) {
26
28
  // eslint-disable-next-line no-console
27
- console.info.apply(console, arguments);
29
+ console.info(...logModule.formatLogByEnv(args));
28
30
  },
29
31
 
30
32
  // Log a debug message. Invokes
@@ -35,15 +37,9 @@ module.exports = function(apos) {
35
37
  // substitution strings in mind. See the
36
38
  // `console.log` documentation.
37
39
 
38
- debug: function(msg) {
40
+ debug: function(...args) {
39
41
  // eslint-disable-next-line no-console
40
- if (console.debug) {
41
- // eslint-disable-next-line no-console
42
- console.debug.apply(console, arguments);
43
- } else {
44
- // eslint-disable-next-line no-console
45
- console.log.apply(console, arguments);
46
- }
42
+ console.debug(...logModule.formatLogByEnv(args));
47
43
  },
48
44
 
49
45
  // Log an error message. The default implementation
@@ -54,9 +50,9 @@ module.exports = function(apos) {
54
50
  // substitution strings in mind. See the
55
51
  // `console.error` documentation.
56
52
 
57
- error: function(msg) {
53
+ error: function(...args) {
58
54
  // eslint-disable-next-line no-console
59
- console.error.apply(console, arguments);
55
+ console.error(...logModule.formatLogByEnv(args));
60
56
  },
61
57
  // Log a warning. The default implementation wraps
62
58
  // `console.warn` and passes on all arguments,
@@ -70,9 +66,15 @@ module.exports = function(apos) {
70
66
  // called for situations less dire than
71
67
  // `apos.util.error`.
72
68
 
73
- warn: function(msg) {
69
+ warn: function(...args) {
74
70
  // eslint-disable-next-line no-console
75
- console.warn.apply(console, arguments);
71
+ console.warn(...logModule.formatLogByEnv(args));
72
+ },
73
+
74
+ // Automatically tear down the logger if available.
75
+
76
+ async destroy() {
77
+ // Nothing to do
76
78
  }
77
79
  };
78
80
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apostrophe",
3
- "version": "3.53.0",
3
+ "version": "3.55.0",
4
4
  "description": "The Apostrophe Content Management System.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test/docs.js CHANGED
@@ -159,7 +159,7 @@ describe('Docs', function() {
159
159
  assert(person._friends[0].slug === 'larry');
160
160
  });
161
161
 
162
- it('should support custom context menu (required only)', async function() {
162
+ it('should support custom context menu (legacy, required only)', async function() {
163
163
  const operation = {
164
164
  context: 'update',
165
165
  action: 'test',
@@ -176,7 +176,7 @@ describe('Docs', function() {
176
176
  moduleName: 'test-people'
177
177
  });
178
178
  });
179
- it('should support custom context menu (with optional)', async function() {
179
+ it('should support custom context menu (legacy, with optional)', async function() {
180
180
  apos.doc.contextOperations = [];
181
181
  const operation = {
182
182
  context: 'update',
@@ -196,6 +196,39 @@ describe('Docs', function() {
196
196
  });
197
197
  });
198
198
 
199
+ it('should support custom context menu (modern, required only)', async function() {
200
+ const operation = {
201
+ context: 'update',
202
+ action: 'test2',
203
+ label: 'Menu Label',
204
+ modal: 'SomeModalComponent'
205
+ };
206
+ const initialLength = apos.doc.contextOperations.length;
207
+
208
+ apos.doc.addContextOperation(operation);
209
+
210
+ assert.strictEqual(apos.doc.contextOperations.length, initialLength + 1);
211
+ // Front end is responsible for inferring moduleName here
212
+ assert.deepStrictEqual(apos.doc.contextOperations.find(op => op.action === 'test2'), operation);
213
+ });
214
+ it('should support custom context menu (modern, with optional)', async function() {
215
+ apos.doc.contextOperations = [];
216
+ const operation = {
217
+ context: 'update',
218
+ action: 'test',
219
+ label: 'Menu Label',
220
+ modal: 'SomeModalComponent',
221
+ manuallyPublished: true,
222
+ modifiers: [ 'danger' ]
223
+ };
224
+ assert.strictEqual(apos.doc.contextOperations.length, 0);
225
+
226
+ apos.doc.addContextOperation(operation);
227
+ assert.strictEqual(apos.doc.contextOperations.length, 1);
228
+ // Front end is responsible for inferring moduleName here
229
+ assert.deepStrictEqual(apos.doc.contextOperations[0], operation);
230
+ });
231
+
199
232
  it('should override custom context menu', async function() {
200
233
  apos.doc.contextOperations = [];
201
234
  const operation1 = {