gscan 5.3.4 → 5.4.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.
package/lib/specs/v6.js CHANGED
@@ -8,7 +8,7 @@ const previousTemplates = previousSpec.templates;
8
8
  const previousRules = previousSpec.rules;
9
9
 
10
10
  // assign new or overwrite existing knownHelpers, templates, or rules here:
11
- let knownHelpers = ['split'];
11
+ let knownHelpers = ['split', 'json', 'color_to_rgba', 'contrast_text_color', 'raw', 'search'];
12
12
  let templates = [];
13
13
  let rules = {
14
14
  'GS090-NO-LIMIT-ALL-IN-GET-HELPER': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gscan",
3
- "version": "5.3.4",
3
+ "version": "5.4.0",
4
4
  "description": "Scans Ghost themes looking for errors, deprecations, features and compatibility",
5
5
  "keywords": [
6
6
  "ghost",
@@ -43,15 +43,15 @@
43
43
  "gscan": "./bin/cli.js"
44
44
  },
45
45
  "dependencies": {
46
- "@sentry/node": "10.42.0",
47
- "@tryghost/config": "2.0.2",
48
- "@tryghost/debug": "2.0.2",
49
- "@tryghost/errors": "3.0.2",
50
- "@tryghost/logging": "4.0.2",
46
+ "@sentry/node": "10.43.0",
47
+ "@tryghost/config": "2.0.3",
48
+ "@tryghost/debug": "2.0.3",
49
+ "@tryghost/errors": "3.0.3",
50
+ "@tryghost/logging": "4.0.3",
51
51
  "@tryghost/nql": "0.12.10",
52
- "@tryghost/pretty-cli": "3.0.2",
53
- "@tryghost/server": "2.0.2",
54
- "@tryghost/zip": "3.0.2",
52
+ "@tryghost/pretty-cli": "3.0.3",
53
+ "@tryghost/server": "2.0.3",
54
+ "@tryghost/zip": "3.0.3",
55
55
  "chalk": "5.6.2",
56
56
  "express": "5.2.1",
57
57
  "express-handlebars": "7.1.3",
@@ -67,13 +67,13 @@
67
67
  "@eslint/eslintrc": "3.3.5",
68
68
  "@eslint/js": "10.0.1",
69
69
  "@tryghost/pro-ship": "1.0.7",
70
- "@vitest/coverage-v8": "4.0.18",
70
+ "@vitest/coverage-v8": "4.1.0",
71
71
  "eslint": "10.0.3",
72
72
  "eslint-plugin-ghost": "3.5.0",
73
73
  "nodemon": "3.1.14",
74
74
  "should": "13.2.3",
75
75
  "sinon": "21.0.2",
76
- "vitest": "4.0.18"
76
+ "vitest": "4.1.0"
77
77
  },
78
78
  "resolutions": {
79
79
  "node-loggly-bulk": "4.0.2",
@@ -81,7 +81,6 @@
81
81
  },
82
82
  "files": [
83
83
  "lib",
84
- "bin",
85
- "app"
84
+ "bin"
86
85
  ]
87
86
  }
@@ -1,39 +0,0 @@
1
- const debug = require('@tryghost/debug')('ghost-version');
2
- const exec = require('child_process').exec;
3
- const config = require('@tryghost/config');
4
-
5
- let ttl;
6
- let ghostVersion;
7
-
8
- const fetchGhostVersion = function fetchGhostVersion() {
9
- debug('Ghost version not set or ttl expired');
10
- exec('npm show ghost version', function (err, stdout, stderr) {
11
- if (err) {
12
- debug('fetchGhostVersion err', err);
13
- }
14
-
15
- if (stderr) {
16
- debug('fetchGhostVersion stderr', stderr);
17
- }
18
-
19
- if (stdout) {
20
- debug('fetchGhostVersion stdout', stdout);
21
- ghostVersion = stdout;
22
- ttl = new Date(Date.now() + config.get('ghostVersionTTL')).valueOf();
23
- }
24
- });
25
- };
26
-
27
- const middleware = function middleware(req, res, next) {
28
- if (!ghostVersion || ttl && ttl < Date.now()) {
29
- fetchGhostVersion();
30
- }
31
-
32
- debug('res.locals.ghostVersion: ' + ghostVersion);
33
- res.locals.ghostVersion = ghostVersion;
34
- next();
35
- };
36
-
37
- fetchGhostVersion();
38
-
39
- module.exports = middleware;
package/app/index.js DELETED
@@ -1,154 +0,0 @@
1
- // Init Sentry middleware
2
- require('./middlewares/sentry');
3
- const sentry = require('@sentry/node');
4
-
5
- // Require rest of the modules
6
- const express = require('express');
7
- const debug = require('@tryghost/debug')('app');
8
- const {create} = require('express-handlebars');
9
- const multer = require('multer');
10
- const server = require('@tryghost/server');
11
- const config = require('@tryghost/config');
12
- const errors = require('@tryghost/errors');
13
- const gscan = require('../lib');
14
- const fs = require('fs-extra');
15
- const path = require('path');
16
- const logRequest = require('./middlewares/log-request');
17
- const uploadValidation = require('./middlewares/upload-validation');
18
- const ghostVer = require('./ghost-version');
19
- const ghostVersions = require('../lib/utils').versions;
20
- const upload = multer({dest: __dirname + '/uploads/'});
21
- const app = express();
22
- const viewsDir = path.join(__dirname, 'tpl');
23
- const scanHbs = create({
24
- extname: '.hbs',
25
- partialsDir: path.join(viewsDir, 'partials'),
26
- layoutsDir: path.join(viewsDir, 'layouts'),
27
- defaultLayout: 'default',
28
- helpers: {
29
- block(name, options) {
30
- const root = options.data && options.data.root;
31
-
32
- if (!root) {
33
- return typeof options.fn === 'function' ? options.fn(this) : '';
34
- }
35
-
36
- const blockCache = root.blockCache || {};
37
- let val = blockCache[name];
38
-
39
- if (val === undefined && typeof options.fn === 'function') {
40
- val = options.fn(this);
41
- }
42
-
43
- if (Array.isArray(val)) {
44
- val = val.join('\n');
45
- }
46
-
47
- return val;
48
- },
49
- contentFor(name, options) {
50
- const root = options.data && options.data.root;
51
-
52
- if (!root) {
53
- return '';
54
- }
55
-
56
- const blockCache = root.blockCache || (root.blockCache = {});
57
- const block = blockCache[name] || (blockCache[name] = []);
58
- block.push(options.fn(this));
59
- return '';
60
- }
61
- }
62
- });
63
-
64
- // Configure express
65
- app.set('x-powered-by', false);
66
- app.set('query parser', false);
67
-
68
- app.engine('hbs', scanHbs.engine);
69
-
70
- app.set('view engine', 'hbs');
71
- app.set('views', viewsDir);
72
-
73
- app.use(logRequest);
74
- app.use(express.static(__dirname + '/public'));
75
- app.use(ghostVer);
76
-
77
- app.get('/', function (req, res) {
78
- res.render('index', {ghostVersions});
79
- });
80
-
81
- app.post('/',
82
- upload.single('theme'),
83
- uploadValidation,
84
- function (req, res, next) {
85
- const zip = {
86
- path: req.file.path,
87
- name: req.file.originalname
88
- };
89
- const options = {
90
- checkVersion: req.body.version || ghostVersions.default
91
- };
92
-
93
- debug('Uploaded: ' + zip.name + ' to ' + zip.path);
94
- debug('Version to check: ' + options.checkVersion);
95
-
96
- let checkError;
97
-
98
- gscan.checkZip(zip, options)
99
- .then(function processResult(theme) {
100
- debug('Checked: ' + zip.name);
101
- res.theme = theme;
102
- }).catch(function (error) {
103
- checkError = error;
104
- }).finally(function () {
105
- debug('attempting to remove: ' + req.file.path);
106
- fs.remove(req.file.path)
107
- .catch(function (removeError) {
108
- debug('failed to remove uploaded file', removeError);
109
- })
110
- .then(function () {
111
- if (checkError) {
112
- debug('Calling next with error');
113
- return next(checkError);
114
- }
115
-
116
- debug('Calling next');
117
- return next();
118
- });
119
- });
120
- },
121
- function doRender(req, res) {
122
- const options = {
123
- checkVersion: req.body.version || ghostVersions.default
124
- };
125
- debug('Formatting result');
126
- const result = gscan.format(res.theme, options);
127
- debug('Rendering result');
128
- scanHbs.handlebars.logger.level = 0;
129
- res.render('result', result);
130
- }
131
- );
132
-
133
- app.use(function (req, res, next) {
134
- next(new errors.NotFoundError({message: 'Page not found'}));
135
- });
136
-
137
- // eslint-disable-next-line no-unused-vars
138
- app.use(function (err, req, res, next) {
139
- let template = 'error';
140
- req.err = err;
141
-
142
- let statusCode = err.statusCode || 500;
143
- res.status(statusCode);
144
-
145
- if (res.statusCode === 404) {
146
- template = 'error-404';
147
- }
148
-
149
- res.render(template, {message: err.message, stack: err.stack, details: err.errorDetails, context: err.context});
150
- });
151
-
152
- sentry.setupExpressErrorHandler(app);
153
-
154
- server.start(app, config.get('port'));
@@ -1,30 +0,0 @@
1
- const randomUUID = require('crypto').randomUUID;
2
- const logging = require('@tryghost/logging');
3
-
4
- /**
5
- * @TODO:
6
- * - move middleware to ignition?
7
- */
8
- module.exports = function logRequest(req, res, next) {
9
- const startTime = Date.now();
10
- const requestId = randomUUID();
11
-
12
- function logResponse() {
13
- res.responseTime = (Date.now() - startTime) + 'ms';
14
- req.requestId = requestId;
15
- req.userId = req.user ? (req.user.id ? req.user.id : req.user) : null;
16
-
17
- if (req.err) {
18
- logging.error({req: req, res: res, err: req.err});
19
- } else {
20
- logging.info({req: req, res: res});
21
- }
22
-
23
- res.removeListener('finish', logResponse);
24
- res.removeListener('close', logResponse);
25
- }
26
-
27
- res.on('finish', logResponse);
28
- res.on('close', logResponse);
29
- next();
30
- };
@@ -1,11 +0,0 @@
1
- const sentryDSN = process.env.SENTRY_DSN;
2
-
3
- if (sentryDSN) {
4
- const Sentry = require('@sentry/node');
5
- const version = require('../../package.json').version;
6
- Sentry.init({
7
- dsn: sentryDSN,
8
- release: 'gscan@' + version,
9
- environment: process.env.NODE_ENV
10
- });
11
- }
@@ -1,43 +0,0 @@
1
- // NOTE: this middleware was extracted from Ghost core validation for theme uploads
2
- // might be useful to unify this logic in the future if it's extracted to separate module
3
- const path = require('path');
4
- const errors = require('@tryghost/errors');
5
-
6
- const checkFileExists = function checkFileExists(fileData) {
7
- return !!(fileData.mimetype && fileData.path);
8
- };
9
-
10
- const checkFileIsValid = function checkFileIsValid(fileData, types, extensions) {
11
- const type = fileData.mimetype;
12
-
13
- if (types.includes(type) && extensions.includes(fileData.ext)) {
14
- return true;
15
- }
16
-
17
- return false;
18
- };
19
-
20
- module.exports = function uploadValidation(req, res, next) {
21
- const extensions = ['.zip'];
22
- const contentTypes = ['application/zip', 'application/x-zip-compressed', 'application/octet-stream'];
23
-
24
- req.file = req.file || {};
25
- req.file.name = req.file.originalname;
26
- req.file.type = req.file.mimetype;
27
-
28
- if (!checkFileExists(req.file)) {
29
- return next(new errors.ValidationError({
30
- message: `"Please select a zip file.`
31
- }));
32
- }
33
-
34
- req.file.ext = path.extname(req.file.name).toLowerCase();
35
-
36
- if (!checkFileIsValid(req.file, contentTypes, extensions)) {
37
- return next(new errors.UnsupportedMediaTypeError({
38
- message: 'Please select a valid zip file.'
39
- }));
40
- }
41
-
42
- next();
43
- };
Binary file
Binary file
Binary file
Binary file