@quasar/render-ssr-error 1.0.4 → 2.0.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/README.md +2 -0
- package/compiled-assets/after-injection +5 -5
- package/compiled-assets/before-injection +39 -12
- package/package.json +18 -19
- package/src/env.js +19 -15
- package/src/error-details.js +1 -1
- package/src/index.js +23 -16
- package/src/stack.js +19 -9
- package/eslint.config.js +0 -30
package/src/env.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from 'node:os'
|
|
2
2
|
|
|
3
|
-
const nodejsVersion = `Node.js ${
|
|
3
|
+
const nodejsVersion = `Node.js ${process.versions.node} ${os.type()}`
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} SsrRequest
|
|
@@ -9,23 +9,27 @@ const nodejsVersion = `Node.js ${ process.versions.node } ${ os.type() }`
|
|
|
9
9
|
/**
|
|
10
10
|
* @param {SsrRequest} req
|
|
11
11
|
*/
|
|
12
|
-
function getRequestProtocol
|
|
13
|
-
const proto = req.headers[
|
|
12
|
+
function getRequestProtocol(req) {
|
|
13
|
+
const proto = req.headers['x-forwarded-proto']
|
|
14
14
|
return proto
|
|
15
|
-
? proto.split(/\s*,\s*/)[
|
|
16
|
-
:
|
|
15
|
+
? proto.split(/\s*,\s*/)[0].toUpperCase()
|
|
16
|
+
: req.socket.encrypted
|
|
17
|
+
? 'HTTPS'
|
|
18
|
+
: 'HTTP'
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* @param {SsrRequest} req
|
|
21
23
|
*/
|
|
22
|
-
function getRequestData
|
|
24
|
+
function getRequestData(req) {
|
|
23
25
|
const url = new URL(req.url, 'http://localhost')
|
|
24
26
|
|
|
25
27
|
return {
|
|
26
28
|
'Node.js': nodejsVersion,
|
|
27
|
-
'Server protocol': `${
|
|
28
|
-
'Remote address':
|
|
29
|
+
'Server protocol': `${getRequestProtocol(req)}/${req.httpVersion}`,
|
|
30
|
+
'Remote address':
|
|
31
|
+
(req.headers['x-forwarded-for'] || '').split(',')[0] ||
|
|
32
|
+
req.socket.remoteAddress,
|
|
29
33
|
'Remote port': req.socket.remotePort,
|
|
30
34
|
'Request URI': req.url,
|
|
31
35
|
'Request method': req.method,
|
|
@@ -37,9 +41,9 @@ function getRequestData (req) {
|
|
|
37
41
|
/**
|
|
38
42
|
* @param {SsrRequest} req
|
|
39
43
|
*/
|
|
40
|
-
function getHeadersData
|
|
44
|
+
function getHeadersData(req) {
|
|
41
45
|
return Object.keys(req.headers).reduce((acc, name) => {
|
|
42
|
-
acc[
|
|
46
|
+
acc[name] = req.headers[name]
|
|
43
47
|
return acc
|
|
44
48
|
}, {})
|
|
45
49
|
}
|
|
@@ -47,19 +51,19 @@ function getHeadersData (req) {
|
|
|
47
51
|
/**
|
|
48
52
|
* @param {SsrRequest} req
|
|
49
53
|
*/
|
|
50
|
-
function getCookiesData
|
|
54
|
+
function getCookiesData(req) {
|
|
51
55
|
const { cookie } = req.headers
|
|
52
56
|
if (cookie === void 0) return {}
|
|
53
57
|
return cookie.split('; ').reduce((acc, entry) => {
|
|
54
58
|
const parts = entry.split('=')
|
|
55
|
-
acc[
|
|
59
|
+
acc[parts.shift().trim()] = decodeURIComponent(parts.join('='))
|
|
56
60
|
return acc
|
|
57
61
|
}, {})
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
function getEnvironmentVariablesData
|
|
64
|
+
function getEnvironmentVariablesData() {
|
|
61
65
|
return Object.keys(process.env).reduce((acc, name) => {
|
|
62
|
-
acc[
|
|
66
|
+
acc[name] = process.env[name]
|
|
63
67
|
return acc
|
|
64
68
|
}, {})
|
|
65
69
|
}
|
|
@@ -67,7 +71,7 @@ function getEnvironmentVariablesData () {
|
|
|
67
71
|
/**
|
|
68
72
|
* @param {SsrRequest} req
|
|
69
73
|
*/
|
|
70
|
-
export function getEnv
|
|
74
|
+
export function getEnv(req) {
|
|
71
75
|
return {
|
|
72
76
|
Request: getRequestData(req),
|
|
73
77
|
Headers: getHeadersData(req),
|
package/src/error-details.js
CHANGED
package/src/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import { getErrorDetails } from './error-details.js'
|
|
|
4
4
|
import { getStack } from './stack.js'
|
|
5
5
|
import { getEnv } from './env.js'
|
|
6
6
|
|
|
7
|
-
function readFile
|
|
7
|
+
function readFile(target) {
|
|
8
8
|
return readFileSync(
|
|
9
|
-
new URL(`../compiled-assets/${
|
|
9
|
+
new URL(`../compiled-assets/${target}-injection`, import.meta.url),
|
|
10
10
|
'utf8'
|
|
11
11
|
)
|
|
12
12
|
}
|
|
@@ -18,14 +18,17 @@ const after = readFile('after')
|
|
|
18
18
|
* @param {{
|
|
19
19
|
* err: Error;
|
|
20
20
|
* req: import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest;
|
|
21
|
-
* res: import('node:http').ServerResponse | import('node:http2').Http2ServerResponse;
|
|
22
21
|
* projectRootFolder?: string;
|
|
23
22
|
* }} params
|
|
24
23
|
*/
|
|
25
|
-
export default function renderSSRError
|
|
24
|
+
export default function renderSSRError({
|
|
25
|
+
err,
|
|
26
|
+
req,
|
|
27
|
+
projectRootFolder = process.cwd()
|
|
28
|
+
}) {
|
|
26
29
|
const data = {
|
|
27
30
|
project: {
|
|
28
|
-
rootFolder: projectRootFolder
|
|
31
|
+
rootFolder: projectRootFolder
|
|
29
32
|
},
|
|
30
33
|
error: getErrorDetails(err),
|
|
31
34
|
stack: getStack(err, projectRootFolder),
|
|
@@ -37,15 +40,19 @@ export default function renderSSRError ({ err, req, res, projectRootFolder = pro
|
|
|
37
40
|
// new URL('./data.json', import.meta.url), JSON.stringify(data, null, 2), 'utf8'
|
|
38
41
|
// )
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
return {
|
|
44
|
+
statusCode: 500,
|
|
45
|
+
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
48
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
49
|
+
Pragma: 'no-cache',
|
|
50
|
+
Expires: '0'
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
html:
|
|
54
|
+
before +
|
|
55
|
+
JSON.stringify(data).replace(/<\/script>/g, '<\\/script>') +
|
|
56
|
+
after
|
|
57
|
+
}
|
|
51
58
|
}
|
package/src/stack.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs'
|
|
|
2
2
|
import { join, relative } from 'node:path'
|
|
3
3
|
import { parse } from 'stack-trace'
|
|
4
4
|
|
|
5
|
-
function getFilename
|
|
5
|
+
function getFilename(filename) {
|
|
6
6
|
if (!filename) {
|
|
7
7
|
return filename
|
|
8
8
|
}
|
|
@@ -12,21 +12,31 @@ function getFilename (filename) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
if (process.env.NVM_DIR && process.versions.node) {
|
|
15
|
-
const nodeFilename = join(
|
|
15
|
+
const nodeFilename = join(
|
|
16
|
+
process.env.NVM_DIR,
|
|
17
|
+
'src/node-v' + process.versions.node,
|
|
18
|
+
'lib',
|
|
19
|
+
filename
|
|
20
|
+
)
|
|
16
21
|
if (existsSync(nodeFilename)) {
|
|
17
22
|
return nodeFilename
|
|
18
23
|
}
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
if (process.env.FNM_DIR && process.versions.node) {
|
|
22
|
-
const nodeFilename = join(
|
|
27
|
+
const nodeFilename = join(
|
|
28
|
+
process.env.FNM_DIR,
|
|
29
|
+
'src/node-versions/v' + process.versions.node,
|
|
30
|
+
'installation/lib',
|
|
31
|
+
filename
|
|
32
|
+
)
|
|
23
33
|
if (existsSync(nodeFilename)) {
|
|
24
34
|
return nodeFilename
|
|
25
35
|
}
|
|
26
36
|
}
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
function getSource
|
|
39
|
+
function getSource(entry) {
|
|
30
40
|
const declaredFilename = entry.getFileName()
|
|
31
41
|
const fileName = getFilename(declaredFilename)
|
|
32
42
|
|
|
@@ -50,9 +60,9 @@ function getSource (entry) {
|
|
|
50
60
|
}
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
const highlightTopOffset = `${
|
|
54
|
-
const highlightLeftOffset = `${
|
|
55
|
-
const maxLineNumberLen = (
|
|
63
|
+
const highlightTopOffset = `${16 /* top padding */ + (lineNumber - startLineNumber - 1) * 21 /* line-height */}px`
|
|
64
|
+
const highlightLeftOffset = `${16 /* left padding */ + entry.getColumnNumber() * 14 /* font-size */}px`
|
|
65
|
+
const maxLineNumberLen = String(startLineNumber + linesList.length - 1).length
|
|
56
66
|
|
|
57
67
|
return {
|
|
58
68
|
fileName,
|
|
@@ -66,7 +76,7 @@ function getSource (entry) {
|
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
78
|
|
|
69
|
-
export function getStack
|
|
79
|
+
export function getStack(err, projectRootFolder) {
|
|
70
80
|
const trace = parse(err)
|
|
71
81
|
|
|
72
82
|
return trace.map(entry => {
|
|
@@ -76,7 +86,7 @@ export function getStack (err, projectRootFolder) {
|
|
|
76
86
|
fileName: relative(projectRootFolder, fileName),
|
|
77
87
|
sourceCode,
|
|
78
88
|
functionName: entry.getTypeName() || entry.getFunctionName(),
|
|
79
|
-
methodName: `${
|
|
89
|
+
methodName: `${entry.isConstructor() ? 'new ' : ''}${entry.getMethodName() || '<anonymous>'}`,
|
|
80
90
|
native: entry.isNative(),
|
|
81
91
|
lineNumber: entry.getLineNumber(),
|
|
82
92
|
columnNumber: entry.getColumnNumber()
|
package/eslint.config.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import jsEsLint from '@eslint/js'
|
|
2
|
-
import quasar from 'eslint-config-quasar'
|
|
3
|
-
import globals from 'globals'
|
|
4
|
-
|
|
5
|
-
/** @type {import('eslint').Linter.Config[]} */
|
|
6
|
-
export default [
|
|
7
|
-
jsEsLint.configs.recommended,
|
|
8
|
-
|
|
9
|
-
...quasar.configs.base,
|
|
10
|
-
...quasar.configs.vue,
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
ignores: [
|
|
14
|
-
'/src-ui/dist',
|
|
15
|
-
'/src-ui/.quasar',
|
|
16
|
-
'/node_modules'
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
languageOptions: {
|
|
22
|
-
ecmaVersion: 'latest',
|
|
23
|
-
sourceType: 'module',
|
|
24
|
-
globals: {
|
|
25
|
-
...globals.browser,
|
|
26
|
-
...globals.node,
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
]
|