@nuxt/server
Advanced tools
Comparing version 2.12.2 to 2.13.0
/*! | ||
* @nuxt/server v2.12.2 (c) 2016-2020 | ||
* @nuxt/server v2.13.0 (c) 2016-2020 | ||
@@ -66,7 +66,6 @@ * - All the amazing contributors | ||
loadingTimeout = 2000, | ||
ssr, | ||
globals | ||
} = {} | ||
) { | ||
const jsdom = await new Promise(function (resolve) { resolve(_interopNamespace(require('jsdom'))); }) | ||
const jsdom = await Promise.resolve().then(function () { return _interopNamespace(require('jsdom')); }) | ||
.then(m => m.default || m) | ||
@@ -109,5 +108,3 @@ .catch((e) => { | ||
// If Nuxt could not be loaded (error from the server-side) | ||
const nuxtExists = window.document.body.innerHTML.includes( | ||
ssr ? `window.${globals.context}` : `<div id="${globals.id}">` | ||
); | ||
const nuxtExists = window.document.body.innerHTML.includes(`id="${globals.id}"`); | ||
@@ -159,3 +156,3 @@ if (!nuxtExists) { | ||
if (redirected) { | ||
if (redirected && context.target !== utils.TARGETS.static) { | ||
await nuxt.callHook('render:routeDone', url, result, context); | ||
@@ -174,2 +171,3 @@ return html | ||
res.statusCode = 304; | ||
await nuxt.callHook('render:beforeResponse', url, result, context); | ||
res.end(); | ||
@@ -203,5 +201,6 @@ await nuxt.callHook('render:routeDone', url, result, context); | ||
const { allowedSources, policies } = options.render.csp; | ||
const cspHeader = options.render.csp.reportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy'; | ||
const isReportOnly = !!options.render.csp.reportOnly; | ||
const cspHeader = isReportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy'; | ||
res.setHeader(cspHeader, getCspString({ cspScriptSrcHashes, allowedSources, policies, isDev: options.dev })); | ||
res.setHeader(cspHeader, getCspString({ cspScriptSrcHashes, allowedSources, policies, isDev: options.dev, isReportOnly })); | ||
} | ||
@@ -213,2 +212,3 @@ | ||
res.setHeader('Content-Length', Buffer.byteLength(html)); | ||
await nuxt.callHook('render:beforeResponse', url, result, context); | ||
res.end(html, 'utf8'); | ||
@@ -247,3 +247,3 @@ await nuxt.callHook('render:routeDone', url, result, context); | ||
const { crossorigin } = options.build; | ||
const { crossorigin } = options.render; | ||
const cors = `${crossorigin ? ` crossorigin=${crossorigin};` : ''}`; | ||
@@ -259,16 +259,14 @@ // `modulepreload` rel attribute only supports script-like `as` value | ||
const getCspString = ({ cspScriptSrcHashes, allowedSources, policies, isDev }) => { | ||
const getCspString = ({ cspScriptSrcHashes, allowedSources, policies, isDev, isReportOnly }) => { | ||
const joinedHashes = cspScriptSrcHashes.join(' '); | ||
const baseCspStr = `script-src 'self'${isDev ? ' \'unsafe-eval\'' : ''} ${joinedHashes}`; | ||
const policyObjectAvailable = typeof policies === 'object' && policies !== null && !Array.isArray(policies); | ||
if (Array.isArray(allowedSources) && allowedSources.length) { | ||
return `${baseCspStr} ${allowedSources.join(' ')}` | ||
return isReportOnly && policyObjectAvailable && !!policies['report-uri'] ? `${baseCspStr} ${allowedSources.join(' ')}; report-uri ${policies['report-uri']};` : `${baseCspStr} ${allowedSources.join(' ')}` | ||
} | ||
const policyObjectAvailable = typeof policies === 'object' && policies !== null && !Array.isArray(policies); | ||
if (policyObjectAvailable) { | ||
const transformedPolicyObject = transformPolicyObject(policies, cspScriptSrcHashes); | ||
return Object.entries(transformedPolicyObject).map(([k, v]) => `${k} ${v.join(' ')}`).join('; ') | ||
return Object.entries(transformedPolicyObject).map(([k, v]) => `${k} ${Array.isArray(v) ? v.join(' ') : v}`).join('; ') | ||
} | ||
@@ -290,15 +288,10 @@ | ||
const errorMiddleware = ({ resources, options }) => async function errorMiddleware (err, req, res, next) { | ||
// ensure statusCode, message and name fields | ||
const errorMiddleware = ({ resources, options }) => async function errorMiddleware (_error, req, res, next) { | ||
// Normalize error | ||
const error = normalizeError(_error, options); | ||
const error = { | ||
statusCode: err.statusCode || 500, | ||
message: err.message || 'Nuxt Server Error', | ||
name: !err.name || err.name === 'Error' ? 'NuxtServerError' : err.name | ||
}; | ||
const sendResponse = (content, type = 'text/html') => { | ||
// Set Headers | ||
res.statusCode = error.statusCode; | ||
res.statusMessage = error.name; | ||
res.statusMessage = 'RuntimeError'; | ||
res.setHeader('Content-Type', type + '; charset=utf-8'); | ||
@@ -308,2 +301,9 @@ res.setHeader('Content-Length', Buffer.byteLength(content)); | ||
// Error headers | ||
if (error.headers) { | ||
for (const name in error.headers) { | ||
res.setHeader(name, error.headers[name]); | ||
} | ||
} | ||
// Send Response | ||
@@ -323,5 +323,6 @@ res.end(content, 'utf-8'); | ||
// We hide actual errors from end users, so show them on server logs | ||
if (err.statusCode !== 404) { | ||
consola.error(err); | ||
if (error.statusCode !== 404) { | ||
consola.error(error); | ||
} | ||
// Json format is compatible with Youch json responses | ||
@@ -342,21 +343,7 @@ const json = { | ||
const errorFull = err instanceof Error | ||
? err | ||
: typeof err === 'string' | ||
? new Error(err) | ||
: new Error(err.message || JSON.stringify(err)); | ||
errorFull.name = error.name; | ||
errorFull.statusCode = error.statusCode; | ||
errorFull.stack = err.stack || undefined; | ||
// Show stack trace | ||
const youch = new Youch( | ||
errorFull, | ||
error, | ||
req, | ||
readSourceFactory({ | ||
srcDir: options.srcDir, | ||
rootDir: options.rootDir, | ||
buildDir: options.buildDir | ||
}), | ||
readSource, | ||
options.router.base, | ||
@@ -375,13 +362,17 @@ true | ||
const readSourceFactory = ({ srcDir, rootDir, buildDir }) => async function readSource (frame) { | ||
// Remove webpack:/// & query string from the end | ||
const sanitizeName = name => name ? name.replace('webpack:///', '').split('?')[0] : null; | ||
frame.fileName = sanitizeName(frame.fileName); | ||
const sanitizeName = name => name ? name.replace('webpack:///', '').split('?')[0] : null; | ||
// Return if fileName is unknown | ||
if (!frame.fileName) { | ||
return | ||
const normalizeError = (_error, { srcDir, rootDir, buildDir }) => { | ||
if (typeof _error === 'string') { | ||
_error = { message: _error }; | ||
} else if (!_error) { | ||
_error = { message: '<empty>' }; | ||
} | ||
// Possible paths for file | ||
const error = new Error(); | ||
error.message = _error.message; | ||
error.name = _error.name; | ||
error.statusCode = _error.statusCode || 500; | ||
error.headers = _error.headers; | ||
const searchPath = [ | ||
@@ -395,17 +386,34 @@ srcDir, | ||
// Scan filesystem for real source | ||
for (const pathDir of searchPath) { | ||
const fullPath = path.resolve(pathDir, frame.fileName); | ||
const source = await fs.readFile(fullPath, 'utf-8').catch(() => null); | ||
if (source) { | ||
frame.contents = source; | ||
frame.fullPath = fullPath; | ||
if (path.isAbsolute(frame.fileName)) { | ||
frame.fileName = path.relative(rootDir, fullPath); | ||
const findInPaths = (fileName) => { | ||
for (const dir of searchPath) { | ||
const fullPath = path.resolve(dir, fileName); | ||
if (fs.existsSync(fullPath)) { | ||
return fullPath | ||
} | ||
return | ||
} | ||
} | ||
return fileName | ||
}; | ||
error.stack = (_error.stack || '') | ||
.split('\n') | ||
.map((line) => { | ||
const match = line.match(/\(([^)]+)\)|([^\s]+\.[^\s]+):/); | ||
if (!match) { | ||
return line | ||
} | ||
const src = match[1] || match[2] || ''; | ||
return line.replace(src, findInPaths(sanitizeName(src))) | ||
}) | ||
.join('\n'); | ||
return error | ||
}; | ||
async function readSource (frame) { | ||
if (fs.existsSync(frame.fileName)) { | ||
frame.fullPath = frame.fileName; // Youch BW compat | ||
frame.contents = await fs.readFile(frame.fileName, 'utf-8'); | ||
} | ||
} | ||
let RANDOM_PORT = '0'; | ||
@@ -617,3 +625,3 @@ | ||
// Initialize vue-renderer | ||
const { VueRenderer } = await new Promise(function (resolve) { resolve(_interopNamespace(require('@nuxt/vue-renderer'))); }); | ||
const { VueRenderer } = await Promise.resolve().then(function () { return _interopNamespace(require('@nuxt/vue-renderer')); }); | ||
@@ -747,3 +755,3 @@ this.serverContext = new ServerContext(this); | ||
// Normalize handler to handle (backward compatiblity) | ||
// Normalize handler to handle (backward compatibility) | ||
if (middleware.handler && !middleware.handle) { | ||
@@ -754,3 +762,3 @@ middleware.handle = middleware.handler; | ||
// Normalize path to route (backward compatiblity) | ||
// Normalize path to route (backward compatibility) | ||
if (middleware.path && !middleware.route) { | ||
@@ -832,3 +840,3 @@ middleware.route = middleware.path; | ||
// Assign _middleware to handle to make accessable from app.stack | ||
// Assign _middleware to handle to make accessible from app.stack | ||
middleware.handle._middleware = middleware; | ||
@@ -860,2 +868,5 @@ | ||
// unload middleware | ||
this.unloadMiddleware(serverStackItem); | ||
// Resolve middleware | ||
@@ -874,2 +885,8 @@ const { route, handle } = this.resolveMiddleware(middleware, serverStackItem.route); | ||
unloadMiddleware ({ handle }) { | ||
if (handle._middleware && typeof handle._middleware.unload === 'function') { | ||
handle._middleware.unload(); | ||
} | ||
} | ||
serverMiddlewarePaths () { | ||
@@ -890,3 +907,2 @@ return this.app.stack.map(({ handle }) => handle._middleware && handle._middleware.entry).filter(Boolean) | ||
loadedCallback = this.globals.loadedCallback, | ||
ssr = this.options.render.ssr, | ||
globals = this.globals | ||
@@ -897,3 +913,2 @@ } = {}) { | ||
loadedCallback, | ||
ssr, | ||
globals | ||
@@ -943,2 +958,3 @@ }) | ||
this.app.stack.forEach(this.unloadMiddleware); | ||
this.app.removeAllListeners(); | ||
@@ -945,0 +961,0 @@ this.app = null; |
{ | ||
"name": "@nuxt/server", | ||
"version": "2.12.2", | ||
"version": "2.13.0", | ||
"repository": "nuxt/nuxt.js", | ||
@@ -11,5 +11,5 @@ "license": "MIT", | ||
"dependencies": { | ||
"@nuxt/config": "2.12.2", | ||
"@nuxt/utils": "2.12.2", | ||
"@nuxt/vue-renderer": "2.12.2", | ||
"@nuxt/config": "2.13.0", | ||
"@nuxt/utils": "2.13.0", | ||
"@nuxt/vue-renderer": "2.13.0", | ||
"@nuxtjs/youch": "^4.2.3", | ||
@@ -19,3 +19,3 @@ "chalk": "^3.0.0", | ||
"connect": "^3.7.0", | ||
"consola": "^2.11.3", | ||
"consola": "^2.13.0", | ||
"etag": "^1.8.1", | ||
@@ -22,0 +22,0 @@ "fresh": "^0.5.2", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27874
786
+ Added@nuxt/config@2.13.0(transitive)
+ Added@nuxt/utils@2.13.0(transitive)
+ Added@nuxt/vue-renderer@2.13.0(transitive)
+ Addedcreate-require@1.1.1(transitive)
+ Addeddefu@2.0.46.1.4(transitive)
+ Addeddestr@1.2.2(transitive)
+ Addeddotenv@8.6.0(transitive)
+ Addedflat@5.0.2(transitive)
+ Addedjiti@0.1.20(transitive)
+ Addedrc9@1.2.4(transitive)
+ Addedserialize-javascript@4.0.0(transitive)
- Removed@nuxt/config@2.12.2(transitive)
- Removed@nuxt/utils@2.12.2(transitive)
- Removed@nuxt/vue-renderer@2.12.2(transitive)
- Removedserialize-javascript@3.1.0(transitive)
Updated@nuxt/config@2.13.0
Updated@nuxt/utils@2.13.0
Updated@nuxt/vue-renderer@2.13.0
Updatedconsola@^2.13.0