@quasar/render-ssr-error 1.0.3 → 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/src/env.js CHANGED
@@ -1,23 +1,36 @@
1
-
2
1
  import os from 'node:os'
3
2
 
4
- const nodejsVersion = `Node.js ${ process.versions.node } ${ os.type() }`
3
+ const nodejsVersion = `Node.js ${process.versions.node} ${os.type()}`
4
+
5
+ /**
6
+ * @typedef {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} SsrRequest
7
+ */
5
8
 
6
- function getRequestProtocol (req) {
7
- const proto = req.headers[ 'X-Forwarded-Proto' ]
9
+ /**
10
+ * @param {SsrRequest} req
11
+ */
12
+ function getRequestProtocol(req) {
13
+ const proto = req.headers['x-forwarded-proto']
8
14
  return proto
9
- ? proto.split(/\s*,\s*/)[ 0 ].toUpperCase()
10
- : (req.connection.encrypted ? 'HTTPS' : 'HTTP')
15
+ ? proto.split(/\s*,\s*/)[0].toUpperCase()
16
+ : req.socket.encrypted
17
+ ? 'HTTPS'
18
+ : 'HTTP'
11
19
  }
12
20
 
13
- function getRequestData (req) {
21
+ /**
22
+ * @param {SsrRequest} req
23
+ */
24
+ function getRequestData(req) {
14
25
  const url = new URL(req.url, 'http://localhost')
15
26
 
16
27
  return {
17
28
  'Node.js': nodejsVersion,
18
- 'Server protocol': `${ getRequestProtocol(req) }/${ req.httpVersion }`,
19
- 'Remote address': (req.headers[ 'x-forwarded-for' ] || '').split(',')[ 0 ] || req.connection.remoteAddress,
20
- 'Remote port': req.connection.remotePort,
29
+ 'Server protocol': `${getRequestProtocol(req)}/${req.httpVersion}`,
30
+ 'Remote address':
31
+ (req.headers['x-forwarded-for'] || '').split(',')[0] ||
32
+ req.socket.remoteAddress,
33
+ 'Remote port': req.socket.remotePort,
21
34
  'Request URI': req.url,
22
35
  'Request method': req.method,
23
36
  'Request pathname': url.pathname,
@@ -25,31 +38,40 @@ function getRequestData (req) {
25
38
  }
26
39
  }
27
40
 
28
- function getHeadersData (req) {
41
+ /**
42
+ * @param {SsrRequest} req
43
+ */
44
+ function getHeadersData(req) {
29
45
  return Object.keys(req.headers).reduce((acc, name) => {
30
- acc[ name ] = req.headers[ name ]
46
+ acc[name] = req.headers[name]
31
47
  return acc
32
48
  }, {})
33
49
  }
34
50
 
35
- function getCookiesData (req) {
51
+ /**
52
+ * @param {SsrRequest} req
53
+ */
54
+ function getCookiesData(req) {
36
55
  const { cookie } = req.headers
37
56
  if (cookie === void 0) return {}
38
57
  return cookie.split('; ').reduce((acc, entry) => {
39
58
  const parts = entry.split('=')
40
- acc[ parts.shift().trim() ] = decodeURIComponent(parts.join('='))
59
+ acc[parts.shift().trim()] = decodeURIComponent(parts.join('='))
41
60
  return acc
42
61
  }, {})
43
62
  }
44
63
 
45
- function getEnvironmentVariablesData () {
64
+ function getEnvironmentVariablesData() {
46
65
  return Object.keys(process.env).reduce((acc, name) => {
47
- acc[ name ] = process.env[ name ]
66
+ acc[name] = process.env[name]
48
67
  return acc
49
68
  }, {})
50
69
  }
51
70
 
52
- export function getEnv (req) {
71
+ /**
72
+ * @param {SsrRequest} req
73
+ */
74
+ export function getEnv(req) {
53
75
  return {
54
76
  Request: getRequestData(req),
55
77
  Headers: getHeadersData(req),
@@ -1,5 +1,4 @@
1
-
2
- export function getErrorDetails (err) {
1
+ export function getErrorDetails(err) {
3
2
  return {
4
3
  name: err.name,
5
4
  message: err.message
package/src/index.js CHANGED
@@ -1,13 +1,12 @@
1
-
2
1
  import { readFileSync } from 'node:fs'
3
2
 
4
3
  import { getErrorDetails } from './error-details.js'
5
4
  import { getStack } from './stack.js'
6
5
  import { getEnv } from './env.js'
7
6
 
8
- function readFile (target) {
7
+ function readFile(target) {
9
8
  return readFileSync(
10
- new URL(`../compiled-assets/${ target }-injection`, import.meta.url),
9
+ new URL(`../compiled-assets/${target}-injection`, import.meta.url),
11
10
  'utf8'
12
11
  )
13
12
  }
@@ -15,8 +14,22 @@ function readFile (target) {
15
14
  const before = readFile('before')
16
15
  const after = readFile('after')
17
16
 
18
- export default function renderSSRError ({ err, req, res, projectRootFolder }) {
17
+ /**
18
+ * @param {{
19
+ * err: Error;
20
+ * req: import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest;
21
+ * projectRootFolder?: string;
22
+ * }} params
23
+ */
24
+ export default function renderSSRError({
25
+ err,
26
+ req,
27
+ projectRootFolder = process.cwd()
28
+ }) {
19
29
  const data = {
30
+ project: {
31
+ rootFolder: projectRootFolder
32
+ },
20
33
  error: getErrorDetails(err),
21
34
  stack: getStack(err, projectRootFolder),
22
35
  env: getEnv(req)
@@ -27,9 +40,19 @@ export default function renderSSRError ({ err, req, res, projectRootFolder }) {
27
40
  // new URL('./data.json', import.meta.url), JSON.stringify(data, null, 2), 'utf8'
28
41
  // )
29
42
 
30
- res.status(500).send(
31
- before
32
- + JSON.stringify(data).replace(/<\/script>/g, '<\\/script>')
33
- + after
34
- )
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
+ }
35
58
  }
package/src/stack.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { existsSync, readFileSync } from 'node:fs'
2
- import { join } from 'node:path'
2
+ import { join, relative } from 'node:path'
3
3
  import { parse } from 'stack-trace'
4
4
 
5
- function getFilename (filename) {
5
+ function getFilename(filename) {
6
6
  if (!filename) {
7
7
  return filename
8
8
  }
@@ -12,14 +12,31 @@ function getFilename (filename) {
12
12
  }
13
13
 
14
14
  if (process.env.NVM_DIR && process.versions.node) {
15
- const nodeFilename = join(process.env.NVM_DIR, 'src/node-v' + process.versions.node, 'lib', filename)
15
+ const nodeFilename = join(
16
+ process.env.NVM_DIR,
17
+ 'src/node-v' + process.versions.node,
18
+ 'lib',
19
+ filename
20
+ )
21
+ if (existsSync(nodeFilename)) {
22
+ return nodeFilename
23
+ }
24
+ }
25
+
26
+ if (process.env.FNM_DIR && process.versions.node) {
27
+ const nodeFilename = join(
28
+ process.env.FNM_DIR,
29
+ 'src/node-versions/v' + process.versions.node,
30
+ 'installation/lib',
31
+ filename
32
+ )
16
33
  if (existsSync(nodeFilename)) {
17
34
  return nodeFilename
18
35
  }
19
36
  }
20
37
  }
21
38
 
22
- function getSource (entry) {
39
+ function getSource(entry) {
23
40
  const declaredFilename = entry.getFileName()
24
41
  const fileName = getFilename(declaredFilename)
25
42
 
@@ -43,9 +60,9 @@ function getSource (entry) {
43
60
  }
44
61
  }
45
62
 
46
- const highlightTopOffset = `${ 16 /* top padding */ + ((lineNumber - startLineNumber - 1) * 21 /* line-height */) }px`
47
- const highlightLeftOffset = `${ 16 /* left padding */ + (entry.getColumnNumber() * 14 /* font-size */) }px`
48
- const maxLineNumberLen = ('' + (startLineNumber + linesList.length - 1)).length
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
49
66
 
50
67
  return {
51
68
  fileName,
@@ -59,17 +76,17 @@ function getSource (entry) {
59
76
  }
60
77
  }
61
78
 
62
- export function getStack (err) {
79
+ export function getStack(err, projectRootFolder) {
63
80
  const trace = parse(err)
64
81
 
65
82
  return trace.map(entry => {
66
83
  const { fileName, sourceCode } = getSource(entry)
67
84
 
68
85
  return {
69
- fileName,
86
+ fileName: relative(projectRootFolder, fileName),
70
87
  sourceCode,
71
88
  functionName: entry.getTypeName() || entry.getFunctionName(),
72
- methodName: `${ entry.isConstructor() ? 'new ' : '' }${ entry.getMethodName() || '<anonymous>' }`,
89
+ methodName: `${entry.isConstructor() ? 'new ' : ''}${entry.getMethodName() || '<anonymous>'}`,
73
90
  native: entry.isNative(),
74
91
  lineNumber: entry.getLineNumber(),
75
92
  columnNumber: entry.getColumnNumber()
package/.eslintignore DELETED
@@ -1,3 +0,0 @@
1
- /src-ui/dist
2
- /src-ui/.quasar
3
- /node_modules
package/.eslintrc.cjs DELETED
@@ -1,70 +0,0 @@
1
-
2
- module.exports = {
3
- // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
4
- // This option interrupts the configuration hierarchy at this file
5
- // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
6
- root: true,
7
-
8
- parserOptions: {
9
- ecmaVersion: 'latest',
10
- sourceType: 'module'
11
- },
12
-
13
- env: {
14
- node: true,
15
- browser: true,
16
- 'vue/setup-compiler-macros': true
17
- },
18
-
19
- // Rules order is important, please avoid shuffling them
20
- extends: [
21
- 'eslint:recommended',
22
- 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
23
- 'standard'
24
- ],
25
-
26
- plugins: [
27
- // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
28
- // required to lint *.vue files
29
- 'vue'
30
- ],
31
-
32
- // add your custom rules here
33
- rules: {
34
- 'brace-style': [ 2, 'stroustrup', { allowSingleLine: true } ],
35
- 'prefer-const': 2,
36
- 'prefer-promise-reject-errors': 'off',
37
- 'multiline-ternary': 'off',
38
- 'no-prototype-builtins': 'off',
39
- 'no-case-declarations': 'off',
40
- 'generator-star-spacing': 'off',
41
- 'arrow-parens': 'off',
42
- 'object-property-newline': 'off',
43
- 'one-var': 'off',
44
- 'no-void': 'off',
45
- 'no-lone-blocks': 'error',
46
- 'no-unused-expressions': [ 'error', { allowShortCircuit: true } ],
47
- 'no-useless-concat': 'error',
48
- 'no-useless-return': 'error',
49
- 'no-unneeded-ternary': 'error',
50
- 'no-confusing-arrow': [ 'error', { allowParens: true } ],
51
- 'operator-linebreak': [ 'error', 'before' ],
52
-
53
- 'array-bracket-spacing': [ 'error', 'always' ],
54
- 'object-curly-spacing': [ 'error', 'always' ],
55
- 'computed-property-spacing': [ 'error', 'always' ],
56
- 'template-curly-spacing': [ 'error', 'always' ],
57
-
58
- 'import/first': 'off',
59
- 'import/named': 'error',
60
- 'import/namespace': 'error',
61
- 'import/default': 'error',
62
- 'import/export': 'error',
63
- 'import/extensions': 'off',
64
- 'import/no-unresolved': 'off',
65
- 'import/no-extraneous-dependencies': 'off',
66
-
67
- // allow debugger during development only
68
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
69
- }
70
- }