apostrophe 3.26.0 → 3.26.1-alpha.2022081201

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/CHANGELOG.md CHANGED
@@ -1,11 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ### UNRELEASED
4
+
5
+ ### Adds
6
+
7
+ * New utility script to help find excessively heavy npm dependencies of apostrophe core.
8
+ * Moved `stylelint` from `dependencies` to `devDependencies`. The benefit may be small because many projects will depend on `stylelint` at project level, but every little bit helps install speed, and it may make a bigger difference if different major versions are in use.
9
+
10
+ ## 3.26.1
11
+
12
+ ### Fixes
13
+
14
+ Hotfix: always waits for the DOM to be ready before initializing the Apostrophe Admin UI. `setTimeout` alone might not guarantee that every time. This issue has apparently become more frequent in the latest versions of Chrome.
15
+ * Modifies the `login` module to return an empty object in the API session cookie response body to avoid potential invalid JSON error if `response.json()` is retrieved.
16
+
3
17
  ## 3.26.0
4
18
 
5
19
  ### Adds
6
20
 
7
21
  * Tasks can now be registered with the `afterModuleReady` flag, which is more useful than `afterModuleInit` because it waits for the module to be more fully initialized, including all "improvements" loaded via npm. The original `afterModuleInit` flag is still supported in case someone was counting on its behavior.
8
22
  * Add `/grid` `POST` route in permission module, in addition to the existing `GET` one, to improve extensibility.
23
+ * `@apostrophecms/express:list-routes` command line task added, to facilitate debugging.
9
24
 
10
25
  ### Changes
11
26
 
@@ -41,8 +41,8 @@ module.exports = {
41
41
  // on the case, such as `@apostrophecms/global:editor` or
42
42
  // `@apostrophecms/page:manager`.
43
43
  //
44
- // Alternatively, an `href` option may be set to an ordinary URL in
45
- // `options`. This creates a basic link in the admin menu.
44
+ // TODO: Alternatively, an `href` option may be set to an ordinary
45
+ // URL in `options`. This creates a basic link in the admin menu.
46
46
  //
47
47
  // `permission` should be an object with `action` and `type`
48
48
  // properties. This determines visibility of the option, securing
@@ -59,13 +59,13 @@ module.exports = {
59
59
  // wish to implement a custom admin bar item not powered by
60
60
  // the `AposModals` app.
61
61
  //
62
- // If `options.contextUtility` is true the item will be displayed in a tray of
63
- // icons just to the left of the page settings gear. If `options.toggle` is also true,
62
+ // If `options.contextUtility` is true, the item will be displayed in a tray of
63
+ // icons just to the right of the login and/or locales menu. If `options.toggle` is also true,
64
64
  // then the button will have the `active` state until toggled
65
- // off again. `options.openTooltip` and `options.closeTooltip` may be
66
- // provided to offer a different tooltip during the active state. Otherwise
67
- // `options.tooltip` is used. The regular label is also present for
68
- // screenreaders only. The contextUtility functionality is typically used for
65
+ // off again. `options.tooltip.deactivate` and `options.tooltip.activate` may be
66
+ // provided to offer a different tooltip during the active versus inactive states,
67
+ // respectively. Otherwise, `options.tooltip` is used. The regular label is also present
68
+ // for screenreaders only. The contextUtility functionality is typically used for
69
69
  // experiences that temporarily change the current editing context.
70
70
  //
71
71
  // If an `options.when` function is provided, it will be invoked with
@@ -460,9 +460,14 @@ module.exports = {
460
460
  ${(tiptap && tiptap.registerCode) || ''}
461
461
  ` +
462
462
  (app ? stripIndent`
463
- setTimeout(() => {
464
- ${app.invokeCode}
465
- }, 0);
463
+ if (document.readyState !== 'loading') {
464
+ setTimeout(invoke, 0);
465
+ } else {
466
+ window.addEventListener('DOMContentLoaded', invoke);
467
+ }
468
+ function invoke() {
469
+ ${app.invokeCode}
470
+ }
466
471
  ` : '') +
467
472
  // No delay on these, they expect to run early like ui/public code
468
473
  // and the first ones invoked set up expected stuff like apos.http
@@ -1,5 +1,3 @@
1
- const StyleLintPlugin = require('stylelint-webpack-plugin');
2
-
3
1
  module.exports = (options, apos) => {
4
2
  return {
5
3
  module: {
@@ -58,11 +56,6 @@ module.exports = (options, apos) => {
58
56
  ]
59
57
  }
60
58
  ]
61
- },
62
- plugins: [
63
- new StyleLintPlugin({
64
- files: [ './node_modules/apostrophe/modules/**/*.{scss,vue}' ]
65
- })
66
- ]
59
+ }
67
60
  };
68
61
  };
@@ -168,6 +168,20 @@ module.exports = {
168
168
  self.apos.util.error('When you do so other modules will also pick up on it and make URLs absolute.');
169
169
  }
170
170
  },
171
+ tasks(self) {
172
+ return {
173
+ 'list-routes': {
174
+ help: 'List all Express routes registered via routes(), apiRoutes(), etc. (not directly via apos.app)',
175
+ async task(argv) {
176
+ for (const info of self.finalModuleMiddlewareAndRoutes) {
177
+ if (info.route) {
178
+ console.log(`${info.method.toUpperCase()} ${info.url}`);
179
+ }
180
+ }
181
+ }
182
+ }
183
+ };
184
+ },
171
185
  handlers(self) {
172
186
  return {
173
187
  'apostrophe:run': {
@@ -648,6 +648,7 @@ module.exports = {
648
648
  if (session) {
649
649
  await self.passportLogin(req, user);
650
650
  await self.clearLoginAttempts(user.username);
651
+ return {};
651
652
  } else {
652
653
  const token = cuid();
653
654
  await self.bearerTokens.insert({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apostrophe",
3
- "version": "3.26.0",
3
+ "version": "3.26.1-alpha.2022081201",
4
4
  "description": "The Apostrophe Content Management System.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -59,7 +59,6 @@
59
59
  "debounce-async": "0.0.2",
60
60
  "deep-get-set": "^1.1.1",
61
61
  "dompurify": "^2.3.1",
62
- "eslint-plugin-promise": "^5.1.0",
63
62
  "express": "^4.16.4",
64
63
  "express-bearer-token": "^2.4.0",
65
64
  "express-cache-on-demand": "^1.0.3",
@@ -102,10 +101,6 @@
102
101
  "sass-loader": "^10.1.1",
103
102
  "server-destroy": "^1.0.1",
104
103
  "sluggo": "^0.3.0",
105
- "stylelint": "^14.6.1",
106
- "stylelint-declaration-strict-value": "^1.8.0",
107
- "stylelint-order": "^5.0.0",
108
- "stylelint-webpack-plugin": "^3.2.0",
109
104
  "tinycolor2": "^1.4.2",
110
105
  "tough-cookie": "^4.0.0",
111
106
  "underscore.string": "^3.3.4",
@@ -134,9 +129,13 @@
134
129
  "nyc": "^15.1.0",
135
130
  "replace-in-file": "^6.1.0",
136
131
  "vue-eslint-parser": "^7.1.1",
137
- "webpack-bundle-analyzer": "^3.9.0"
132
+ "webpack-bundle-analyzer": "^3.9.0",
133
+ "eslint-plugin-promise": "^5.1.0",
134
+ "stylelint": "^14.6.1",
135
+ "stylelint-declaration-strict-value": "^1.8.0",
136
+ "stylelint-order": "^5.0.0"
138
137
  },
139
138
  "browserslist": [
140
139
  "ie >= 10"
141
140
  ]
142
- }
141
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-disable node/no-path-concat */
3
+
4
+ const fs = require('fs');
5
+
6
+ const trueDeps = JSON.parse(fs.readFileSync(`${__dirname}/../package-lock.json`)).packages;
7
+ const deps = {};
8
+ for (let [ name, props ] of Object.entries(trueDeps)) {
9
+ if (props.dev) {
10
+ continue;
11
+ }
12
+ const lastIndex = name.lastIndexOf('node_modules/');
13
+ if (lastIndex !== -1) {
14
+ name = name.substring(lastIndex + 13);
15
+ }
16
+ deps[name] = props;
17
+ }
18
+ const costs = new Map();
19
+ for (const name of Object.keys(deps[''].dependencies)) {
20
+ costs.set(name, countWeight(name));
21
+ }
22
+
23
+ function countWeight(name) {
24
+ const subDeps = deps[name].dependencies || {};
25
+ let weight = 0;
26
+ for (const name of Object.keys(subDeps)) {
27
+ weight += countWeight(name);
28
+ }
29
+ return weight + 1;
30
+ }
31
+
32
+ const sorted = [ ...costs.entries() ].sort((a, b) => a[1] - b[1]);
33
+ for (const [ name, cost ] of sorted) {
34
+ console.log(`${name} has ${cost} sub-dependencies`);
35
+ }
36
+
37
+ const nonDevDeps = Object.keys(trueDeps).filter(name => !trueDeps[name].dev).length;
38
+ console.log(`Total dependencies: ${nonDevDeps}`);