gscan 4.26.0 → 4.28.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.
@@ -6,6 +6,8 @@ module.exports = {
6
6
  'GS090-NO-PRODUCTS-HELPER': require('./lint-no-products-helper'),
7
7
  'GS090-NO-PRODUCT-DATA-HELPER': require('./lint-no-product-data-helper'),
8
8
  'GS090-NO-PRODUCTS-DATA-HELPER': require('./lint-no-products-data-helper'),
9
+ 'GS090-NO-MEMBER-PRODUCTS-DATA-HELPER': require('./lint-no-member-products-data-helper'),
10
+ 'GS090-NO-PRICE-DATA-HELPER': require('./lint-no-price-data-helper'),
9
11
  'no-multi-param-conditionals': require('./lint-no-multi-param-conditionals'),
10
12
  'no-nested-async-helpers': require('./lint-no-nested-async-helpers'),
11
13
  'no-prev-next-post-outside-post-context': require('./lint-no-prev-next-post-outside-post-context'),
@@ -0,0 +1,24 @@
1
+ const Rule = require('./base');
2
+ const {getNodeName, logNode} = require('../helpers');
3
+
4
+ module.exports = class NoMemberProductsHelper extends Rule {
5
+ _checkForHelperName(node) {
6
+ const nodeName = getNodeName(node);
7
+ const isMatchingHelper = (nodeName === '@member.products');
8
+
9
+ if (isMatchingHelper) {
10
+ this.log({
11
+ message: `${logNode(node)} should not be used`,
12
+ line: node.loc && node.loc.start.line,
13
+ column: node.loc && node.loc.start.column,
14
+ source: this.sourceForNode(node)
15
+ });
16
+ }
17
+ }
18
+
19
+ visitor() {
20
+ return {
21
+ MustacheStatement: this._checkForHelperName.bind(this)
22
+ };
23
+ }
24
+ };
@@ -0,0 +1,24 @@
1
+ const Rule = require('./base');
2
+ const {getNodeName, logNode} = require('../helpers');
3
+
4
+ module.exports = class NoPriceDataHelper extends Rule {
5
+ _checkForHelperName(node) {
6
+ const nodeName = getNodeName(node);
7
+ const isMatchingHelper = (nodeName.startsWith('@price.'));
8
+
9
+ if (isMatchingHelper) {
10
+ this.log({
11
+ message: `${logNode(node)} should not be used`,
12
+ line: node.loc && node.loc.start.line,
13
+ column: node.loc && node.loc.start.column,
14
+ source: this.sourceForNode(node)
15
+ });
16
+ }
17
+ }
18
+
19
+ visitor() {
20
+ return {
21
+ MustacheStatement: this._checkForHelperName.bind(this)
22
+ };
23
+ }
24
+ };
@@ -2,7 +2,7 @@ const Rule = require('./base');
2
2
  const {getNodeName, logNode} = require('../helpers');
3
3
 
4
4
  module.exports = class NoProductsHelper extends Rule {
5
- _checkForHelerInPostContext(node) {
5
+ _checkForHelperName(node) {
6
6
  const nodeName = getNodeName(node);
7
7
  const isProductsHelper = (nodeName === '@product');
8
8
 
@@ -18,7 +18,7 @@ module.exports = class NoProductsHelper extends Rule {
18
18
 
19
19
  visitor() {
20
20
  return {
21
- MustacheStatement: this._checkForHelerInPostContext.bind(this)
21
+ MustacheStatement: this._checkForHelperName.bind(this)
22
22
  };
23
23
  }
24
24
  };
@@ -2,7 +2,7 @@ const Rule = require('./base');
2
2
  const {getNodeName, logNode} = require('../helpers');
3
3
 
4
4
  module.exports = class NoProductsHelper extends Rule {
5
- _checkForHelerInPostContext(node) {
5
+ _checkForHelperName(node) {
6
6
  const nodeName = getNodeName(node);
7
7
  const isProductsHelper = (nodeName === '@products');
8
8
 
@@ -18,7 +18,7 @@ module.exports = class NoProductsHelper extends Rule {
18
18
 
19
19
  visitor() {
20
20
  return {
21
- MustacheStatement: this._checkForHelerInPostContext.bind(this)
21
+ MustacheStatement: this._checkForHelperName.bind(this)
22
22
  };
23
23
  }
24
24
  };
@@ -2,7 +2,7 @@ const Rule = require('./base');
2
2
  const {getNodeName, logNode} = require('../helpers');
3
3
 
4
4
  module.exports = class NoProductsHelper extends Rule {
5
- _checkForHelerInPostContext(node) {
5
+ _checkForHelperName(node) {
6
6
  const nodeName = getNodeName(node);
7
7
  const isProductsHelper = (nodeName === 'products');
8
8
 
@@ -18,7 +18,7 @@ module.exports = class NoProductsHelper extends Rule {
18
18
 
19
19
  visitor() {
20
20
  return {
21
- MustacheStatement: this._checkForHelerInPostContext.bind(this)
21
+ MustacheStatement: this._checkForHelperName.bind(this)
22
22
  };
23
23
  }
24
24
  };
@@ -58,6 +58,23 @@ let rules = {
58
58
  Find more information about the <code>{{#get "tiers"}}</code> property <a href="${docsBaseUrl}helpers/tiers/" target=_blank>here</a>.`,
59
59
  helper: '{{@products}}'
60
60
  },
61
+ 'GS090-NO-MEMBER-PRODUCTS-DATA-HELPER': {
62
+ level: 'error',
63
+ rule: 'The <code>{{@member.products}}</code> helper should be replaces with <code>{{@member.subscriptions}}</code>',
64
+ details: oneLineTrim`The <code>{{@member.products}}</code> helper has been deprecated in favor of <code>{{@member.subscriptions}}</code><br>
65
+ The <code>{{@member.products}}</code> helper was removed in Ghost v5 and should not be used.
66
+ Find more information about the <code>{{@member.subscriptions}}</code> property <a href="${docsBaseUrl}members/#member-subscriptions" target=_blank>here</a>.`,
67
+ helper: '{{@member.products}}'
68
+ },
69
+ 'GS090-NO-PRICE-DATA-HELPER': {
70
+ level: 'error',
71
+ fatal: true,
72
+ rule: 'The <code>{{@price}}</code> data helper should be replaces with <code>{{price}}</code> and <code>{{@member.subscriptions}}</code>',
73
+ details: oneLineTrim`The <code>{{@price}}</code> data helper has been deprecated in favor of <code>{{price}}</code> and <code>{{@member.subscriptions}}</code><br>
74
+ The <code>{{@price}}</code> helper was removed in Ghost v5 and should not be used.
75
+ Find more information about the <code>{{price}}</code> helper <a href="${docsBaseUrl}members/#the-price-helper" target=_blank>here</a>.`,
76
+ helper: '{{@price}}'
77
+ },
61
78
 
62
79
  // Updated v1 & v2 rules
63
80
  'GS001-DEPR-BLOG': {
@@ -545,6 +562,15 @@ let rules = {
545
562
  regex: /{{\s*?#if\s*?post\.author\.image\s*?}}/g,
546
563
  helper: '{{#if post.author.image}}'
547
564
  },
565
+ 'GS001-DEPR-LABS-MEMBERS': {
566
+ level: 'error',
567
+ rule: 'Replace the <code>{{@labs.members}}</code> helper with <code>{{@site.members_enabled}}</code>',
568
+ details: oneLineTrim`The <code>{{@labs.members}}</code> helper was replaced with <code>{{@site.members_enabled}}</code><br>
569
+ The <code>{{@labs.members}}</code> helper will always return <code>null</code> and evaluate to <code>false</code>.
570
+ Find more information about the <code>@labs</code> property <a href="${docsBaseUrl}helpers/labs/" target=_blank>here</a>.`,
571
+ regex: /@labs\.members/g,
572
+ helper: '{{@labs.members}}'
573
+ },
548
574
  'GS001-DEPR-SPL': {
549
575
  level: 'error',
550
576
  fatal: true,
@@ -597,7 +623,7 @@ let rules = {
597
623
  },
598
624
  'GS001-DEPR-SITE-LANG': {
599
625
  level: 'error',
600
- fatal: true,
626
+ fatal: false,
601
627
  rule: 'The <code>{{@site.lang}}</code> helper should be replaced with <code>{{@site.locale}}</code>',
602
628
  details: oneLineTrim`Replace <code>{{@site.lang}}</code> helper with <code>{{@site.locale}}</code>.<br>
603
629
  The <code>{{@site.lang}}</code> helper is removed in v5 version of Ghost and should not be used.
@@ -613,6 +639,25 @@ let rules = {
613
639
  Find more information about the <code>{{get}}</code> helper <a href="${docsBaseUrl}helpers/get/" target=_blank>here</a>.`,
614
640
  regex: /{{\s*?#get ("|')\s*users("|')\s*/g,
615
641
  helper: '{{#get "users"}}'
642
+ },
643
+ 'GS001-DEPR-ESC': {
644
+ level: 'error',
645
+ fatal: true,
646
+ rule: 'Replace <code>{{error.code}}</code> with <code>{{error.statusCode}}</code>',
647
+ details: oneLineTrim`The usage of <code>{{error.code}}</code> is deprecated and should be replaced with <code>{{error.statusCode}}</code>.<br>
648
+ When in <code>error</code> context, e. g. in the <code>error.hbs</code> template, replace <code>{{code}}</code> with <code>{{statusCode}}</code>.<br>
649
+ Find more information about the <code>error.hbs</code> template <a href="${docsBaseUrl}structure/#errorhbs" target=_blank>here</a>.`,
650
+ regex: /{{\s*?(?:error\.)?(code)\s*?}}/g,
651
+ helper: '{{error.code}}'
652
+ },
653
+ 'GS001-DEPR-CURR-SYM': {
654
+ level: 'error',
655
+ fatal: true,
656
+ rule: 'Replace <code>{{[#].currency_symbol}}</code> with <code>{{price currency=currency}}</code>.',
657
+ details: oneLineTrim`The hardcoded <code>currency_symbol</code> attribute was removed in favour of passing the currency to updated <code>{{price}}</code> helper.
658
+ Find more information about the updated <code>{{price}}</code> helper <a href="${docsBaseUrl}members/#the-price-helper" target=_blank>here</a>.`,
659
+ helper: '{{[#].currency_symbol}}',
660
+ regex: /currency_symbol/g
616
661
  }
617
662
  };
618
663
 
@@ -623,6 +668,8 @@ templates = _.union(previousTemplates, templates);
623
668
  // as well as adding any new rule to the spec.
624
669
  // Furthermore, replace the usage of the old doc URLs that we're linking to, with the
625
670
  // new version.
671
+ delete previousRules['GS010-PJ-GHOST-API-V01'];
672
+
626
673
  rules = _.each(_.merge({}, previousRules, rules), function replaceDocsUrl(value) {
627
674
  value.details = value.details.replace(prevDocsBaseUrlRegEx, docsBaseUrl);
628
675
  });
package/lib/specs/v4.js CHANGED
@@ -24,7 +24,7 @@ function cssCardRule(cardName, className) {
24
24
  }
25
25
 
26
26
  // assign new or overwrite existing knownHelpers, templates, or rules here:
27
- let knownHelpers = ['match'];
27
+ let knownHelpers = ['match', 'tiers'];
28
28
  let templates = [];
29
29
  let rules = {
30
30
  // New rules
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gscan",
3
- "version": "4.26.0",
3
+ "version": "4.28.0",
4
4
  "description": "Scans Ghost themes looking for errors, deprecations, features and compatibility",
5
5
  "keywords": [
6
6
  "ghost",
@@ -14,7 +14,7 @@
14
14
  "url": "git@github.com:TryGhost/gscan.git"
15
15
  },
16
16
  "engines": {
17
- "node": "^12.22.1 || ^14.17.0 || ^16.13.0"
17
+ "node": "^14.17.0 || ^16.13.0"
18
18
  },
19
19
  "bugs": {
20
20
  "url": "https://github.com/TryGhost/gscan/issues"
@@ -40,26 +40,26 @@
40
40
  "gscan": "./bin/cli.js"
41
41
  },
42
42
  "dependencies": {
43
- "@sentry/node": "6.19.3",
43
+ "@sentry/node": "6.19.7",
44
44
  "@tryghost/config": "0.2.2",
45
45
  "@tryghost/debug": "0.1.11",
46
- "@tryghost/errors": "1.2.7",
47
- "@tryghost/logging": "2.1.1",
48
- "@tryghost/pretty-cli": "1.2.24",
46
+ "@tryghost/errors": "1.2.12",
47
+ "@tryghost/logging": "2.1.8",
48
+ "@tryghost/pretty-cli": "1.2.27",
49
49
  "@tryghost/server": "0.1.4",
50
- "@tryghost/zip": "1.1.22",
50
+ "@tryghost/zip": "1.1.25",
51
51
  "bluebird": "3.7.2",
52
52
  "chalk": "4.1.2",
53
53
  "common-tags": "1.8.2",
54
- "express": "4.17.3",
54
+ "express": "4.18.1",
55
55
  "express-hbs": "2.4.0",
56
- "fs-extra": "10.0.1",
57
- "glob": "7.2.0",
56
+ "fs-extra": "10.1.0",
57
+ "glob": "7.2.2",
58
58
  "lodash": "4.17.21",
59
59
  "multer": "1.4.4",
60
60
  "pluralize": "8.0.0",
61
61
  "require-dir": "1.2.0",
62
- "semver": "7.3.5",
62
+ "semver": "7.3.7",
63
63
  "uuid": "8.3.2",
64
64
  "validator": "13.0.0"
65
65
  },
@@ -67,11 +67,11 @@
67
67
  "eslint": "8.1.0",
68
68
  "eslint-plugin-ghost": "2.1.0",
69
69
  "istanbul": "0.4.5",
70
- "mocha": "9.0.2",
70
+ "mocha": "10.0.0",
71
71
  "nodemon": "2.0.7",
72
72
  "rewire": "6.0.0",
73
73
  "should": "13.2.3",
74
- "sinon": "13.0.0"
74
+ "sinon": "14.0.0"
75
75
  },
76
76
  "files": [
77
77
  "lib",