mirror of
https://github.com/JonasunderscoreJones/api-worker.git
synced 2025-10-23 18:39:19 +02:00
Initial commit (by create-cloudflare CLI)
This commit is contained in:
commit
58a42872a0
1745 changed files with 741893 additions and 0 deletions
382
node_modules/youch/src/Youch.js
generated
vendored
Normal file
382
node_modules/youch/src/Youch.js
generated
vendored
Normal file
|
@ -0,0 +1,382 @@
|
|||
'use strict'
|
||||
|
||||
/*
|
||||
* youch
|
||||
*
|
||||
* (c) Harminder Virk <virk@adonisjs.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const cookie = require('cookie')
|
||||
const Mustache = require('mustache')
|
||||
const { fileURLToPath } = require('url')
|
||||
const StackTracey = require('stacktracey')
|
||||
const { serialize } = require('v8')
|
||||
const VIEW_PATH = './error.compiled.mustache'
|
||||
|
||||
const viewTemplate = fs.readFileSync(path.join(__dirname, VIEW_PATH), 'utf-8')
|
||||
|
||||
class Youch {
|
||||
constructor (error, request, options = {}) {
|
||||
this.options = options
|
||||
this.options.postLines = options.postLines || 5
|
||||
this.options.preLines = options.preLines || 5
|
||||
|
||||
this._filterHeaders = ['cookie', 'connection']
|
||||
this.error = error
|
||||
this.request = request
|
||||
this.links = []
|
||||
this.showAllFrames = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source code for a given file. It unable to
|
||||
* read file it resolves the promise with a null.
|
||||
*
|
||||
* @param {Object} frame
|
||||
* @return {Promise}
|
||||
*/
|
||||
_getFrameSource (frame) {
|
||||
let path = frame
|
||||
.file
|
||||
.replace(/dist\/webpack:\//g, '') // unix
|
||||
.replace(/dist\\webpack:\\/g, '') // windows
|
||||
|
||||
/**
|
||||
* We ignore the error when "fileURLToPath" is unable to parse
|
||||
* the path, since returning the frame source is an optional
|
||||
* thing
|
||||
*/
|
||||
try {
|
||||
path = path.startsWith('file:') ? fileURLToPath(path) : path
|
||||
} catch {
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
fs.readFile(path, 'utf-8', (error, contents) => {
|
||||
if (error) {
|
||||
resolve(null)
|
||||
return
|
||||
}
|
||||
|
||||
const lines = contents.split(/\r?\n/)
|
||||
const lineNumber = frame.line
|
||||
|
||||
resolve({
|
||||
pre: lines.slice(
|
||||
Math.max(0, lineNumber - (this.options.preLines + 1)),
|
||||
lineNumber - 1
|
||||
),
|
||||
line: lines[lineNumber - 1],
|
||||
post: lines.slice(lineNumber, lineNumber + this.options.postLines)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the error stack and returns serialized
|
||||
* frames out of it.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
_parseError () {
|
||||
return new Promise((resolve, reject) => {
|
||||
const stack = new StackTracey(this.error)
|
||||
Promise.all(
|
||||
stack.items.map(async (frame) => {
|
||||
if (this._isNode(frame)) {
|
||||
return Promise.resolve(frame)
|
||||
}
|
||||
return this._getFrameSource(frame).then((context) => {
|
||||
frame.context = context
|
||||
return frame
|
||||
})
|
||||
})
|
||||
)
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the context with code for a given
|
||||
* frame.
|
||||
*
|
||||
* @param {Object}
|
||||
* @return {Object}
|
||||
*/
|
||||
_getContext (frame) {
|
||||
if (!frame.context) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
start: frame.line - (frame.context.pre || []).length,
|
||||
pre: frame.context.pre.join('\n'),
|
||||
line: frame.context.line,
|
||||
post: frame.context.post.join('\n')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns classes to be used inside HTML when
|
||||
* displaying the frames list.
|
||||
*
|
||||
* @param {Object}
|
||||
* @param {Number}
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
_getDisplayClasses (frame) {
|
||||
const classes = []
|
||||
if (!frame.isApp) {
|
||||
classes.push('native-frame')
|
||||
}
|
||||
|
||||
return classes
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the view using HTML
|
||||
*
|
||||
* @param {String}
|
||||
* @param {Object}
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
_compileView (view, data) {
|
||||
return Mustache.render(view, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes frame to a usable error object.
|
||||
*
|
||||
* @param {Object}
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
_serializeFrame (frame) {
|
||||
return {
|
||||
file: frame.fileRelative,
|
||||
filePath: frame.file.startsWith('file:')
|
||||
? fileURLToPath(frame.file).replaceAll('\\', '/')
|
||||
: frame.file,
|
||||
line: frame.line,
|
||||
callee: frame.callee,
|
||||
calleeShort: frame.calleeShort,
|
||||
column: frame.column,
|
||||
context: this._getContext(frame),
|
||||
isModule: frame.thirdParty,
|
||||
isNative: frame.native,
|
||||
isApp: this._isApp(frame)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether frame belongs to nodejs
|
||||
* or not.
|
||||
*
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
_isNode (frame) {
|
||||
if (frame.native) {
|
||||
return true
|
||||
}
|
||||
|
||||
const filename = frame.file || ''
|
||||
if (filename.startsWith('node:')) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
// return !path.isAbsolute(filename) && filename[0] !== '.'
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether code belongs to the app
|
||||
* or not.
|
||||
*
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
_isApp (frame) {
|
||||
return !this._isNode(frame) && !this._isNodeModule(frame)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether frame belongs to a node_module or
|
||||
* not
|
||||
*
|
||||
* @method _isNodeModule
|
||||
*
|
||||
* @param {Object} frame
|
||||
*
|
||||
* @return {Boolean}
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_isNodeModule (frame) {
|
||||
return (frame.file || '').indexOf('node_modules/') > -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes stack to Mustache friendly object to
|
||||
* be used within the view. Optionally can pass
|
||||
* a callback to customize the frames output.
|
||||
*
|
||||
* @param {Object}
|
||||
* @param {Function} [callback]
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
_serializeData (stack, callback) {
|
||||
callback = callback || this._serializeFrame.bind(this)
|
||||
return {
|
||||
message: this.error.message,
|
||||
help: this.error.help,
|
||||
cause: this.error.cause,
|
||||
name: this.error.name,
|
||||
status: this.error.status,
|
||||
frames:
|
||||
stack instanceof Array === true
|
||||
? stack.filter((frame) => frame.file).map(callback)
|
||||
: []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a serialized object with important
|
||||
* information.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
_serializeRequest () {
|
||||
const headers = []
|
||||
const cookies = []
|
||||
|
||||
if (this.request.headers) {
|
||||
Object.keys(this.request.headers).forEach((key) => {
|
||||
if (this._filterHeaders.indexOf(key) > -1) {
|
||||
return
|
||||
}
|
||||
headers.push({
|
||||
key: key.toUpperCase(),
|
||||
value: this.request.headers[key]
|
||||
})
|
||||
})
|
||||
|
||||
if (this.request.headers.cookie) {
|
||||
const parsedCookies = cookie.parse(this.request.headers.cookie || '')
|
||||
Object.keys(parsedCookies).forEach((key) => {
|
||||
cookies.push({ key, value: parsedCookies[key] })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
url: this.request.url,
|
||||
httpVersion: this.request.httpVersion,
|
||||
method: this.request.method,
|
||||
connection: this.request.headers ? this.request.headers.connection : null,
|
||||
headers,
|
||||
cookies
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the link `callback` which
|
||||
* will be processed when rendering
|
||||
* the HTML view.
|
||||
*
|
||||
* @param {Function} callback
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
addLink (callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this.links.push(callback)
|
||||
return this
|
||||
}
|
||||
|
||||
throw new Error('Pass a callback function to "addLink"')
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the state of showing all frames by default
|
||||
*/
|
||||
toggleShowAllFrames () {
|
||||
this.showAllFrames = !this.showAllFrames
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns error stack as JSON.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
toJSON () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._parseError()
|
||||
.then((stack) => {
|
||||
resolve({
|
||||
error: this._serializeData(stack)
|
||||
})
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML representation of the error stack
|
||||
* by parsing the stack into frames and getting
|
||||
* important info out of it.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
toHTML (templateState) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._parseError()
|
||||
.then((stack) => {
|
||||
let foundActiveFrame = false
|
||||
|
||||
const data = this._serializeData(stack, (frame, index) => {
|
||||
const serializedFrame = this._serializeFrame(frame)
|
||||
const classes = this._getDisplayClasses(serializedFrame)
|
||||
|
||||
/**
|
||||
* Adding active class to first app framework
|
||||
*/
|
||||
if (!foundActiveFrame && (serializedFrame.isApp || index + 1 === stack.length)) {
|
||||
classes.push('active')
|
||||
foundActiveFrame = true
|
||||
}
|
||||
|
||||
serializedFrame.classes = classes.join(' ')
|
||||
|
||||
return serializedFrame
|
||||
})
|
||||
|
||||
if (templateState) {
|
||||
Object.assign(data, templateState)
|
||||
}
|
||||
|
||||
if (this.request) {
|
||||
data.request = this._serializeRequest()
|
||||
}
|
||||
|
||||
data.links = this.links.map((renderLink) => renderLink(data))
|
||||
data.loadFA = !!data.links.find((link) => link.includes('fa-'))
|
||||
data.showAllFrames = this.showAllFrames
|
||||
|
||||
return resolve(this._compileView(viewTemplate, data))
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Youch
|
Loading…
Add table
Add a link
Reference in a new issue