gscan 4.43.4 → 4.43.6

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.
@@ -3,7 +3,7 @@ const spec = require('../specs');
3
3
  const {versions, getPackageJSON} = require('../utils');
4
4
  const ASTLinter = require('../ast-linter');
5
5
 
6
- function processFileFunction(files, failures, rules) {
6
+ function processFileFunction(files, failures, rules, partialVerificationCache) {
7
7
  // This rule is needed to find partials
8
8
  // Partials are needed for a full parsing
9
9
  if (!rules['mark-used-partials']) {
@@ -16,6 +16,16 @@ function processFileFunction(files, failures, rules) {
16
16
  return;
17
17
  }
18
18
 
19
+ const fileName = themeFile.file;
20
+
21
+ // Check if the file is a partial
22
+ const isPartial = fileName.startsWith('partials/');
23
+
24
+ // Skip if already cached (for partials only)
25
+ if (isPartial && partialVerificationCache.has(fileName)) {
26
+ return;
27
+ }
28
+
19
29
  const astResults = linter.verify({
20
30
  parsed: themeFile.parsed,
21
31
  rules,
@@ -30,6 +40,11 @@ function processFileFunction(files, failures, rules) {
30
40
  });
31
41
  }
32
42
 
43
+ // Cache the result for this partial
44
+ if (isPartial) {
45
+ partialVerificationCache.set(fileName, astResults);
46
+ }
47
+
33
48
  linter.partials.forEach(({normalizedName}) => {
34
49
  const file = files.find(f => f.normalizedFile === `partials/${normalizedName}.hbs`);
35
50
  if (file) {
@@ -62,15 +77,16 @@ const checkTemplateSyntax = function checkTemplateSyntax(theme, options) {
62
77
  });
63
78
 
64
79
  _.each(rulesToCheck, function (check, ruleCode) {
80
+ const partialVerificationCache = new Map();
65
81
  const failures = [];
66
82
  const processFile = processFileFunction(
67
83
  theme.files,
68
84
  failures,
69
85
  {
70
86
  [ruleCode]: require(`../ast-linter/rules`)[ruleCode]
71
- }
87
+ },
88
+ partialVerificationCache
72
89
  );
73
-
74
90
  const linter = new ASTLinter({
75
91
  partials: theme.partials,
76
92
  inlinePartials: [],
@@ -36,7 +36,8 @@ function getLogger({theme, rule, file = null}) {
36
36
  }
37
37
 
38
38
  function applyRule(rule, theme) {
39
- // The result variable is passed around to keep a state through the full rull lifecycle
39
+ const partialVerificationCache = new Map();
40
+ // The result variable is passed around to keep a state through the full lifecycle
40
41
  const result = {};
41
42
  try {
42
43
  // Check if the rule is enabled (optional)
@@ -56,7 +57,7 @@ function applyRule(rule, theme) {
56
57
  // Run the main function on each theme file (optional)
57
58
  if (typeof rule.eachFile === 'function') {
58
59
  _.each(theme.files , function (themeFile) {
59
- rule.eachFile({file: themeFile, theme, log: getLogger({theme, rule}), result});
60
+ rule.eachFile({file: themeFile, theme, log: getLogger({theme, rule}), result, partialVerificationCache});
60
61
  });
61
62
  }
62
63
 
@@ -71,7 +72,7 @@ function applyRule(rule, theme) {
71
72
  }
72
73
  }
73
74
 
74
- function parseWithAST({theme, log, file, rules, callback}){
75
+ function parseWithAST({theme, log, file, rules, callback, partialVerificationCache}){
75
76
  const linter = new ASTLinter();
76
77
 
77
78
  // This rule is needed to find partials
@@ -86,6 +87,14 @@ function parseWithAST({theme, log, file, rules, callback}){
86
87
  return;
87
88
  }
88
89
 
90
+ const fileName = themeFile.file;
91
+ // Check if the file is a partial
92
+ const isPartial = fileName.startsWith('partials/');
93
+ // Skip if already cached (for partials only)
94
+ if (isPartial && partialVerificationCache.has(fileName)) {
95
+ return;
96
+ }
97
+
89
98
  const astResults = linter.verify({
90
99
  parsed: themeFile.parsed,
91
100
  rules,
@@ -93,6 +102,11 @@ function parseWithAST({theme, log, file, rules, callback}){
93
102
  moduleId: themeFile.file
94
103
  });
95
104
 
105
+ // Cache the result for this partial
106
+ if (isPartial) {
107
+ partialVerificationCache.set(fileName, astResults);
108
+ }
109
+
96
110
  if (astResults.length) {
97
111
  log.failure({
98
112
  message: astResults[0].message
@@ -122,13 +136,13 @@ const ruleImplementations = {
122
136
  init: ({result}) => {
123
137
  result.customThemeSettings = new Set();
124
138
  },
125
- eachFile: ({file, theme, log, result}) => {
139
+ eachFile: ({file, theme, log, result, partialVerificationCache}) => {
126
140
  let templateTest = file.file.match(/(?<!partials\/.+?)\.hbs$/);
127
141
 
128
142
  if (templateTest) {
129
143
  parseWithAST({file, theme, rules: {
130
144
  'mark-used-custom-theme-setting': require(`../ast-linter/rules/mark-used-custom-theme-settings`)
131
- }, log, callback: (linter) => {
145
+ }, log, partialVerificationCache, callback: (linter) => {
132
146
  linter.customThemeSettings.forEach((variable) => {
133
147
  result.customThemeSettings.add(variable);
134
148
  });
@@ -36,6 +36,8 @@ function getLogger({theme, rule, file = null}) {
36
36
  }
37
37
 
38
38
  function applyRule(rule, theme) {
39
+ const partialVerificationCache = new Map();
40
+
39
41
  // The result variable is passed around to keep a state through the full lifecycle
40
42
  const result = {};
41
43
  try {
@@ -56,7 +58,7 @@ function applyRule(rule, theme) {
56
58
  // Run the main function on each theme file (optional)
57
59
  if (typeof rule.eachFile === 'function') {
58
60
  _.each(theme.files, function (themeFile) {
59
- rule.eachFile({file: themeFile, theme, log: getLogger({theme, rule}), result});
61
+ rule.eachFile({file: themeFile, theme, log: getLogger({theme, rule}), result, partialVerificationCache});
60
62
  });
61
63
  }
62
64
 
@@ -71,11 +73,11 @@ function applyRule(rule, theme) {
71
73
  }
72
74
  }
73
75
 
74
- function parseWithAST({theme, log, file, rules, callback}) {
76
+ function parseWithAST({theme, log, file, rules, callback, partialVerificationCache}) {
75
77
  const linter = new ASTLinter();
76
78
 
77
- // // This rule is needed to find partials
78
- // // Partials are needed for a full parsing
79
+ // This rule is needed to find partials
80
+ // Partials are needed for a full parsing
79
81
  if (!rules['mark-used-partials']) {
80
82
  rules['mark-used-partials'] = require(`../ast-linter/rules/mark-used-partials`);
81
83
  }
@@ -86,6 +88,14 @@ function parseWithAST({theme, log, file, rules, callback}) {
86
88
  return;
87
89
  }
88
90
 
91
+ const fileName = themeFile.file;
92
+ // Check if the file is a partial
93
+ const isPartial = fileName.startsWith('partials/');
94
+ // Skip if already cached (for partials only)
95
+ if (isPartial && partialVerificationCache.has(fileName)) {
96
+ return;
97
+ }
98
+
89
99
  const astResults = linter.verify({
90
100
  parsed: themeFile.parsed,
91
101
  rules,
@@ -93,6 +103,11 @@ function parseWithAST({theme, log, file, rules, callback}) {
93
103
  moduleId: themeFile.file
94
104
  });
95
105
 
106
+ // Cache the result for this partial
107
+ if (isPartial) {
108
+ partialVerificationCache.set(fileName, astResults);
109
+ }
110
+
96
111
  if (astResults.length) {
97
112
  log.failure({
98
113
  message: astResults[0].message,
@@ -121,13 +136,13 @@ const ruleImplementations = {
121
136
  init: ({result}) => {
122
137
  result.pageBuilderProperties = new Set();
123
138
  },
124
- eachFile: ({file, theme, log, result}) => {
139
+ eachFile: ({file, theme, log, result, partialVerificationCache}) => {
125
140
  const templateTest = file.file.match(/(?<!partials\/.+?)\.hbs$/);
126
141
 
127
142
  if (templateTest) {
128
143
  parseWithAST({file, theme, rules: {
129
144
  'mark-used-page-properties': require(`../ast-linter/rules/mark-used-page-properties`)
130
- }, log, callback: (linter) => {
145
+ }, log, partialVerificationCache, callback: (linter) => {
131
146
  linter.usedPageProperties.forEach((variable) => {
132
147
  result.pageBuilderProperties.add(variable);
133
148
  });
@@ -149,14 +164,14 @@ const ruleImplementations = {
149
164
  },
150
165
  'GS110-NO-UNKNOWN-PAGE-BUILDER-USAGE': {
151
166
  isEnabled: true,
152
- eachFile: ({file, theme, log}) => {
167
+ eachFile: ({file, theme, log, partialVerificationCache}) => {
153
168
  const templateTest = file.file.match(/(?<!partials\/.+?)\.hbs$/);
154
169
 
155
170
  if (templateTest) {
156
171
  parseWithAST({
157
172
  file, theme, rules: {
158
173
  'no-unknown-page-properties': require(`../ast-linter/rules/lint-no-unknown-page-properties`)
159
- }, log, callback: () => {}
174
+ }, log, partialVerificationCache, callback: () => {}
160
175
  });
161
176
  }
162
177
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gscan",
3
- "version": "4.43.4",
3
+ "version": "4.43.6",
4
4
  "description": "Scans Ghost themes looking for errors, deprecations, features and compatibility",
5
5
  "keywords": [
6
6
  "ghost",
@@ -77,7 +77,7 @@
77
77
  "nodemon": "2.0.7",
78
78
  "rewire": "6.0.0",
79
79
  "should": "13.2.3",
80
- "sinon": "18.0.0"
80
+ "sinon": "19.0.2"
81
81
  },
82
82
  "files": [
83
83
  "lib",