Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@fastify/view

Package Overview
Dependencies
Maintainers
18
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fastify/view - npm Package Compare versions

Comparing version 8.2.0 to 9.0.0

.prettierignore

20

benchmark/fastify.js
'use strict'
process.env.NODE_ENV = 'production'
const fastify = require('fastify')()
fastify.register(require('../index'), {
engine: {
ejs: require('ejs')
}
require('./setup.js')({
engine: { ejs: require('ejs') },
route: (req, reply) => { reply.view('index.ejs', { text: 'text' }) }
})
fastify.get('/', (req, reply) => {
reply.view('../templates/index.ejs', { text: 'text' })
})
fastify.listen({ port: 3000 }, err => {
if (err) throw err
console.log(`server listening on ${fastify.server.address().port}`)
})
'use strict'
const { readFile } = require('node:fs/promises')
const fp = require('fastify-plugin')
const { accessSync, existsSync, mkdirSync, readdirSync, readFile } = require('node:fs')
const { accessSync, existsSync, mkdirSync, readdirSync } = require('node:fs')
const { basename, dirname, extname, join, resolve } = require('node:path')

@@ -9,11 +9,9 @@ const HLRU = require('hashlru')

function fastifyView (fastify, opts, next) {
async function fastifyView (fastify, opts) {
if (!opts.engine) {
next(new Error('Missing engine'))
return
throw new Error('Missing engine')
}
const type = Object.keys(opts.engine)[0]
if (supportedEngines.indexOf(type) === -1) {
next(new Error(`'${type}' not yet supported, PR? :)`))
return
throw new Error(`'${type}' not yet supported, PR? :)`)
}

@@ -32,2 +30,16 @@ const charset = opts.charset || 'utf-8'

/**
* @type {Map<string, Promise>}
*/
const readFileMap = new Map()
function readFileSemaphore (filePath) {
if (readFileMap.has(filePath) === false) {
const promise = readFile(filePath, 'utf-8')
readFileMap.set(filePath, promise)
return promise.finally(() => readFileMap.delete(filePath))
}
return readFileMap.get(filePath)
}
function templatesDirIsValid (_templatesDir) {

@@ -60,11 +72,6 @@ if (Array.isArray(_templatesDir) && type !== 'nunjucks') {

try {
templatesDirIsValid(templatesDir)
templatesDirIsValid(templatesDir)
if (globalLayoutFileName) {
layoutIsValid(globalLayoutFileName)
}
} catch (error) {
next(error)
return
if (globalLayoutFileName) {
layoutIsValid(globalLayoutFileName)
}

@@ -90,3 +97,3 @@

function viewDecorator () {
function viewDecorator (page) {
const args = Array.from(arguments)

@@ -99,18 +106,9 @@

const promise = new Promise((resolve, reject) => {
renderer.apply({
getHeader: () => { },
header: () => { },
send: result => {
if (result instanceof Error) {
reject(result)
return
}
let promise = !page ? Promise.reject(new Error('Missing page')) : renderer.apply(this, args)
resolve(result)
}
}, args)
})
if (minify) {
promise = promise.then((result) => minify(result, globalOptions.htmlMinifierOptions))
}
if (done && typeof done === 'function') {
if (typeof done === 'function') {
promise.then(done.bind(null, null), done)

@@ -129,4 +127,20 @@ return

fastify.decorateReply(propertyName, function () {
renderer.apply(this, arguments)
fastify.decorateReply(propertyName, async function (page) {
if (!page) {
this.send(new Error('Missing page'))
}
try {
const result = await renderer.apply(this, arguments)
if (!this.getHeader('Content-Type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
if (minify && !isPathExcludedMinification(this)) {
this.send(minify(result, globalOptions.htmlMinifierOptions))
} else {
this.send(result)
}
} catch (err) {
this.send(err)
}
return this

@@ -179,19 +193,17 @@ })

function isPathExcludedMinification (currentPath, pathsToExclude) {
return (pathsToExclude && Array.isArray(pathsToExclude)) ? pathsToExclude.includes(currentPath) : false
}
const minify = typeof globalOptions.useHtmlMinifier?.minify === 'function'
? globalOptions.useHtmlMinifier.minify
: null
function useHtmlMinification (globalOpts, requestedPath) {
return globalOptions.useHtmlMinifier &&
(typeof globalOptions.useHtmlMinifier.minify === 'function') &&
!isPathExcludedMinification(requestedPath, globalOptions.pathsToExcludeHtmlMinifier)
}
const minifyExcludedPaths = Array.isArray(globalOptions.pathsToExcludeHtmlMinifier)
? new Set(globalOptions.pathsToExcludeHtmlMinifier)
: null
function getRequestedPath (fastify) {
return (fastify && fastify.request) ? fastify.request.routeOptions.url : null
return fastify?.request?.routeOptions.url ?? null
}
function onTemplatesLoaded (file, data, callback, requestedPath) {
if (useHtmlMinification(globalOptions, requestedPath)) {
data = globalOptions.useHtmlMinifier.minify(data, globalOptions.htmlMinifierOptions || {})
}
function isPathExcludedMinification (that) {
return minifyExcludedPaths?.has(getRequestedPath(that))
}
function onTemplatesLoaded (file, data) {
if (type === 'handlebars') {

@@ -201,10 +213,10 @@ data = engine.compile(data, globalOptions.compileOptions)

lru.set(file, data)
callback(null, data)
return data
}
// Gets template as string (or precompiled for Handlebars)
// from LRU cache or filesystem.
const getTemplate = function (file, callback, requestedPath) {
const getTemplate = async function (file) {
if (typeof file === 'function') {
callback(null, file)
return
return file
}

@@ -218,48 +230,28 @@ let isRaw = false

if (data && prod) {
callback(null, data)
return
return data
}
if (isRaw) {
onTemplatesLoaded(file, file, callback, requestedPath)
return
return onTemplatesLoaded(file, file)
}
readFile(join(templatesDir, file), 'utf-8', (err, data) => {
if (err) {
callback(err, null)
return
}
onTemplatesLoaded(file, data, callback, requestedPath)
})
const fileData = await readFileSemaphore(join(templatesDir, file))
return onTemplatesLoaded(file, fileData)
}
// Gets partials as collection of strings from LRU cache or filesystem.
const getPartials = function (page, { partials, requestedPath }, callback) {
const getPartials = async function (page, { partials, requestedPath }) {
const cacheKey = getPartialsCacheKey(page, partials, requestedPath)
const partialsObj = lru.get(cacheKey)
if (partialsObj && prod) {
callback(null, partialsObj)
return partialsObj
} else {
let filesToLoad = Object.keys(partials).length
if (filesToLoad === 0) {
callback(null, {})
return
const partialKeys = Object.keys(partials)
if (partialKeys.length === 0) {
return {}
}
let error = null
const partialsHtml = {}
Object.keys(partials).forEach((key, index) => {
readFile(join(templatesDir, partials[key]), 'utf-8', (err, data) => {
if (err) {
error = err
}
if (useHtmlMinification(globalOptions, requestedPath)) {
data = globalOptions.useHtmlMinifier.minify(data, globalOptions.htmlMinifierOptions || {})
}
partialsHtml[key] = data
if (--filesToLoad === 0) {
lru.set(cacheKey, partialsHtml)
callback(error, partialsHtml)
}
})
})
await Promise.all(partialKeys.map(async (key) => {
partialsHtml[key] = await readFileSemaphore(join(templatesDir, partials[key]))
}))
lru.set(cacheKey, partialsHtml)
return partialsHtml
}

@@ -280,51 +272,18 @@ }

function readCallbackEnd (that, compile, data, localOptions) {
let cachedPage
try {
cachedPage = compile(data)
} catch (error) {
cachedPage = error
}
if (!that.getHeader('content-type')) {
that.header('Content-Type', 'text/html; charset=' + charset)
}
const requestedPath = getRequestedPath(that)
if (!localOptions) {
localOptions = globalOptions
}
if (type === 'ejs' && ((localOptions.async ?? globalOptions.async) || cachedPage instanceof Promise)) {
cachedPage.then(html => {
if (useHtmlMinification(globalOptions, requestedPath)) {
html = globalOptions.useHtmlMinifier.minify(html, globalOptions.htmlMinifierOptions || {})
function readCallbackParser (page, html, localOptions) {
if ((type === 'ejs') && viewExt && !globalOptions.includer) {
globalOptions.includer = (originalPath, parsedPath) => {
return {
filename: parsedPath || join(templatesDir, originalPath + '.' + viewExt)
}
that.send(html)
}).catch(err => that.send(err))
return
}
}
if (useHtmlMinification(globalOptions, requestedPath)) {
cachedPage = globalOptions.useHtmlMinifier.minify(cachedPage, globalOptions.htmlMinifierOptions || {})
}
that.send(cachedPage)
}
if (localOptions) {
for (const key in globalOptions) {
if (!Object.prototype.hasOwnProperty.call(localOptions, key)) localOptions[key] = globalOptions[key]
}
} else localOptions = globalOptions
function readCallbackParser (that, page, html, localOptions) {
let compiledPage
try {
if ((type === 'ejs') && viewExt && !globalOptions.includer) {
globalOptions.includer = (originalPath, parsedPath) => {
return {
filename: parsedPath || join(templatesDir, originalPath + '.' + viewExt)
}
}
}
if (localOptions) {
for (const key in globalOptions) {
if (!Object.prototype.hasOwnProperty.call(localOptions, key)) localOptions[key] = globalOptions[key]
}
} else localOptions = globalOptions
compiledPage = engine.compile(html, localOptions)
} catch (error) {
that.send(error)
return
}
const compiledPage = engine.compile(html, localOptions)
lru.set(page, compiledPage)

@@ -334,13 +293,5 @@ return compiledPage

function readCallback (that, page, data, localOptions) {
return function _readCallback (err, html) {
if (err) {
that.send(err)
return
}
globalOptions.filename = join(templatesDir, page)
const compiledPage = readCallbackParser(that, page, html, localOptions)
readCallbackEnd(that, compiledPage, data, localOptions)
}
function readCallback (page, data, localOptions, html) {
globalOptions.filename = join(templatesDir, page)
return readCallbackParser(page, html, localOptions)
}

@@ -376,12 +327,6 @@

function view (page, data, opts) {
if (!page) {
this.send(new Error('Missing page'))
return
}
async function view (page, data, opts) {
data = Object.assign({}, defaultCtx, this.locals, data)
if (typeof page === 'function') {
readCallbackEnd(this, page, data, opts)
return
return page(data)
}

@@ -396,37 +341,24 @@ let isRaw = false

}
const toHtml = lru.get(page)
if (toHtml && prod) {
readCallbackEnd(this, toHtml, data, opts)
return
return toHtml(data)
} else if (isRaw) {
const compiledPage = readCallbackParser(page, page, opts)
return compiledPage(data)
}
if (isRaw) {
const compiledPage = readCallbackParser(this, page, page, opts)
readCallbackEnd(this, compiledPage, data, opts)
return
}
readFile(join(templatesDir, page), 'utf8', readCallback(this, page, data, opts))
const file = await readFileSemaphore(join(templatesDir, page))
const render = readCallback(page, data, opts, file)
return render(data)
}
function viewEjs (page, data, opts) {
if (opts && opts.layout) {
try {
layoutIsValid(opts.layout)
const that = this
return withLayout(viewEjs, opts.layout).call(that, page, data)
} catch (error) {
this.send(error)
return
}
async function viewEjs (page, data, opts) {
if (opts?.layout) {
layoutIsValid(opts.layout)
return withLayout(viewEjs, opts.layout).call(this, page, data)
}
if (!page) {
this.send(new Error('Missing page'))
return
}
data = Object.assign({}, defaultCtx, this.locals, data)
if (typeof page === 'function') {
readCallbackEnd(this, page, data, opts)
return
return page(data)
}

@@ -444,18 +376,14 @@ let isRaw = false

if (toHtml && prod) {
readCallbackEnd(this, toHtml, data, opts)
return
return toHtml(data)
} else if (isRaw) {
const compiledPage = readCallbackParser(page, page, opts)
return compiledPage(data)
}
if (isRaw) {
const compiledPage = readCallbackParser(this, page, page, opts)
readCallbackEnd(this, compiledPage, data, opts)
return
}
readFile(join(templatesDir, page), 'utf8', readCallback(this, page, data, opts))
const file = await readFileSemaphore(join(templatesDir, page))
const render = readCallback(page, data, opts, file)
return render(data)
}
function viewArtTemplate (page, data) {
if (!page) {
this.send(new Error('Missing page'))
return
}
async function viewArtTemplate (page, data) {
data = Object.assign({}, defaultCtx, this.locals, data)

@@ -492,18 +420,6 @@

try {
const html = render(page, data)
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
} catch (error) {
this.send(error)
}
return render(page, data)
}
function viewNunjucks (page, data) {
if (!page) {
this.send(new Error('Missing page'))
return
}
async function viewNunjucks (page, data) {
data = Object.assign({}, defaultCtx, this.locals, data)

@@ -514,3 +430,2 @@ let render

page = getPage(page, 'njk')
// template = nunjucksEnv.getTemplate(page)
render = nunjucksEnv.render.bind(nunjucksEnv, page)

@@ -524,32 +439,20 @@ } else if (typeof page === 'object' && typeof page.render === 'function') {

}
render(data, (err, html) => {
const requestedPath = getRequestedPath(this)
if (err) return this.send(err)
if (useHtmlMinification(globalOptions, requestedPath)) {
html = globalOptions.useHtmlMinifier.minify(html, globalOptions.htmlMinifierOptions || {})
}
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
return new Promise((resolve, reject) => {
render(data, (err, html) => {
if (err) {
reject(err)
return
}
resolve(html)
})
})
}
function viewHandlebars (page, data, opts) {
if (opts && opts.layout) {
try {
layoutIsValid(opts.layout)
const that = this
return withLayout(viewHandlebars, opts.layout).call(that, page, data)
} catch (error) {
this.send(error)
return
}
async function viewHandlebars (page, data, opts) {
if (opts?.layout) {
layoutIsValid(opts.layout)
return withLayout(viewHandlebars, opts.layout).call(this, page, data)
}
if (!page) {
this.send(new Error('Missing page'))
return
}
let options

@@ -570,50 +473,19 @@

const requestedPath = getRequestedPath(this)
getTemplate(page, (err, template) => {
if (err) {
this.send(err)
return
}
const template = await getTemplate(page)
if (prod) {
try {
const html = template(data, options)
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
} catch (e) {
this.send(e)
}
} else {
getPartials(type, { partials: globalOptions.partials || {}, requestedPath }, (err, partialsObject) => {
if (err) {
this.send(err)
return
}
if (prod) {
const html = template(data, options)
return html
} else {
const partialsObject = await getPartials(type, { partials: globalOptions.partials || {}, requestedPath })
try {
Object.keys(partialsObject).forEach((name) => {
engine.registerPartial(name, engine.compile(partialsObject[name], globalOptions.compileOptions))
})
Object.keys(partialsObject).forEach((name) => {
engine.registerPartial(name, engine.compile(partialsObject[name], globalOptions.compileOptions))
})
const html = template(data, options)
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
} catch (e) {
this.send(e)
}
})
}
}, requestedPath)
return template(data, options)
}
}
function viewMustache (page, data, opts) {
if (!page) {
this.send(new Error('Missing page'))
return
}
async function viewMustache (page, data, opts) {
const options = Object.assign({}, opts)

@@ -626,33 +498,16 @@ data = Object.assign({}, defaultCtx, this.locals, data)

const requestedPath = getRequestedPath(this)
getTemplate(page, (err, templateString) => {
if (err) {
this.send(err)
return
}
getPartials(page, { partials: options.partials || {}, requestedPath }, (err, partialsObject) => {
if (err) {
this.send(err)
return
}
let html
if (typeof templateString === 'function') {
html = templateString(data, partialsObject)
} else {
html = engine.render(templateString, data, partialsObject)
}
const templateString = await getTemplate(page)
const partialsObject = await getPartials(page, { partials: options.partials || {}, requestedPath })
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
})
}, requestedPath)
let html
if (typeof templateString === 'function') {
html = templateString(data, partialsObject)
} else {
html = engine.render(templateString, data, partialsObject)
}
return html
}
function viewTwig (page, data, opts) {
if (!page) {
this.send(new Error('Missing page'))
return
}
async function viewTwig (page, data, opts) {
data = Object.assign({}, defaultCtx, globalOptions, this.locals, data)

@@ -671,23 +526,15 @@ let render

}
render(data, (err, html) => {
const requestedPath = getRequestedPath(this)
if (err) {
return this.send(err)
}
if (useHtmlMinification(globalOptions, requestedPath)) {
html = globalOptions.useHtmlMinifier.minify(html, globalOptions.htmlMinifierOptions || {})
}
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
return new Promise((resolve, reject) => {
render(data, (err, html) => {
if (err) {
reject(err)
return
}
resolve(html)
})
})
}
function viewLiquid (page, data, opts) {
if (!page) {
this.send(new Error('Missing page'))
return
}
async function viewLiquid (page, data, opts) {
data = Object.assign({}, defaultCtx, this.locals, data)

@@ -706,34 +553,11 @@ let render

render(data, opts)
.then((html) => {
const requestedPath = getRequestedPath(this)
if (useHtmlMinification(globalOptions, requestedPath)) {
html = globalOptions.useHtmlMinifier.minify(html, globalOptions.htmlMinifierOptions || {})
}
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
})
.catch((err) => {
this.send(err)
})
return render(data, opts)
}
function viewDot (renderModule) {
return function _viewDot (page, data, opts) {
if (opts && opts.layout) {
try {
layoutIsValid(opts.layout)
const that = this
return withLayout(dotRender, opts.layout).call(that, page, data)
} catch (error) {
this.send(error)
return
}
return async function _viewDot (page, data, opts) {
if (opts?.layout) {
layoutIsValid(opts.layout)
return withLayout(dotRender, opts.layout).call(this, page, data)
}
if (!page) {
this.send(new Error('Missing page'))
return
}
data = Object.assign({}, defaultCtx, this.locals, data)

@@ -748,31 +572,12 @@ let render

}
let html = render(data)
const requestedPath = getRequestedPath(this)
if (useHtmlMinification(globalOptions, requestedPath)) {
html = globalOptions.useHtmlMinifier.minify(html, globalOptions.htmlMinifierOptions || {})
}
if (!this.getHeader('content-type')) {
this.header('Content-Type', 'text/html; charset=' + charset)
}
this.send(html)
return render(data)
}
}
function viewEta (page, data, opts) {
if (opts && opts.layout) {
try {
layoutIsValid(opts.layout)
const that = this
return withLayout(viewEta, opts.layout).call(that, page, data)
} catch (error) {
this.send(error)
return
}
async function viewEta (page, data, opts) {
if (opts?.layout) {
layoutIsValid(opts.layout)
return withLayout(viewEta, opts.layout).call(this, page, data)
}
if (!page) {
this.send(new Error('Missing page'))
return
}
if (globalOptions.templatesSync) {

@@ -794,33 +599,7 @@ engine.templatesSync = globalOptions.templatesSync

const sendContent = html => {
if (
config.useHtmlMinifier &&
typeof config.useHtmlMinifier.minify === 'function' &&
!isPathExcludedMinification(getRequestedPath(this), config.pathsToExcludeHtmlMinifier)
) {
html = config.useHtmlMinifier.minify(
html,
config.htmlMinifierOptions || {}
)
}
this.header('Content-Type', 'text/html; charset=' + charset)
this.send(html)
}
data = Object.assign({}, defaultCtx, this.locals, data)
if (typeof page === 'function') {
try {
const ret = page.call(engine, data, config)
if (ret instanceof Promise) {
ret.then(sendContent).catch(err => {
this.send(err)
})
} else {
sendContent(ret)
}
} catch (err) {
this.send(err)
}
return
const ret = await page.call(engine, data, config)
return ret
}

@@ -842,16 +621,5 @@

if (opts?.async ?? globalOptions.async) {
renderAsync(page, data, config)
.then((res) => {
sendContent(res)
})
.catch(err => {
this.send(err)
})
return renderAsync(page, data, config)
} else {
try {
const html = render(page, data, config)
sendContent(html)
} catch (err) {
this.send(err)
}
return render(page, data, config)
}

@@ -861,14 +629,6 @@ }

if (prod && type === 'handlebars' && globalOptions.partials) {
getPartials(type, { partials: globalOptions.partials, requestedPath: getRequestedPath(this) }, (err, partialsObject) => {
if (err) {
next(err)
return
}
Object.keys(partialsObject).forEach((name) => {
engine.registerPartial(name, engine.compile(partialsObject[name], globalOptions.compileOptions))
})
next()
const partialsObject = await getPartials(type, { partials: globalOptions.partials, requestedPath: getRequestedPath(this) })
Object.keys(partialsObject).forEach((name) => {
engine.registerPartial(name, engine.compile(partialsObject[name], globalOptions.compileOptions))
})
} else {
next()
}

@@ -878,19 +638,8 @@

if (layout) {
return function (page, data, opts) {
if (opts && opts.layout) throw new Error('A layout can either be set globally or on render, not both.')
const that = this
return async function (page, data, opts) {
if (opts?.layout) throw new Error('A layout can either be set globally or on render, not both.')
data = Object.assign({}, defaultCtx, this.locals, data)
render.call({
getHeader: () => { },
header: () => { },
send: (result) => {
if (result instanceof Error) {
that.send(result)
return
}
data = Object.assign(data, { body: result })
render.call(that, layout, data, opts)
}
}, page, data, opts)
const result = await render.call(this, page, data, opts)
data = Object.assign(data, { body: result })
return render.call(this, layout, data, opts)
}

@@ -897,0 +646,0 @@ }

{
"name": "@fastify/view",
"version": "8.2.0",
"version": "9.0.0",
"description": "Template plugin for Fastify",
"main": "index.js",
"type": "commonjs",
"types": "types/index.d.ts",
"scripts": {
"benchmark": "node benchmark.js",
"example": "node examples/example.js",

@@ -48,2 +50,3 @@ "example-with-options": "node examples/example-ejs-with-some-options.js",

"art-template": "^4.13.2",
"autocannon": "^7.15.0",
"cross-env": "^7.0.2",

@@ -67,3 +70,3 @@ "dot": "^1.1.3",

"tap": "^16.0.0",
"tsd": "^0.29.0",
"tsd": "^0.30.0",
"twig": "^1.13.3"

@@ -70,0 +73,0 @@ },

@@ -1203,1 +1203,52 @@ 'use strict'

})
test('reply.view with ejs engine and failed call to render when onError hook defined', t => {
t.plan(6)
const fastify = Fastify()
const ejs = require('ejs')
fastify.register(require('../index'), {
engine: {
ejs
}
})
fastify.get('/invalid', (req, reply) => {
// Note the mistake in the ternary statement -- the second `?` should be a `:`
reply.view({
raw: '<p><%= true ? "text" ? "text2" %></p>'
})
})
fastify.get('/valid', (req, reply) => {
reply.view({
raw: '<%= true ? "text" : "text2" %>'
})
})
// when onError hook is defined, certain errors (such as calls to reply.send inside the `onError` hook) are uncaught
fastify.addHook('onError', async (request, reply, err) => {})
fastify.listen({ port: 0 }, err => {
t.error(err)
// request route with invalid template, followed by route with valid template
// in order to ensure server does not crash after first request
sget({
method: 'GET',
url: `http://localhost:${fastify.server.address().port}/invalid`
}, (err, response) => {
t.error(err)
t.equal(response.statusCode, 500)
sget({
method: 'GET',
url: `http://localhost:${fastify.server.address().port}/valid`
}, (err, response, body) => {
t.error(err)
t.equal('text', body.toString())
t.equal(response.statusCode, 200)
fastify.close()
})
})
})
})

@@ -847,3 +847,3 @@ 'use strict'

get (k) {
if (typeof this.cache[k] !== 'undefined') {
if (this.cache[k] !== undefined) {
t.pass()

@@ -850,0 +850,0 @@ }

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc