@hapipal/toys
Advanced tools
Comparing version
172
lib/index.js
'use strict'; | ||
const Stream = require('stream'); | ||
const { AsyncLocalStorage } = require('async_hooks'); | ||
@@ -112,113 +111,2 @@ const Hoek = require('@hapi/hoek'); | ||
exports.reacher = (chain, options) => { | ||
if (chain === false || | ||
chain === null || | ||
typeof chain === 'undefined') { | ||
return (obj) => obj; | ||
} | ||
options = options || {}; | ||
if (typeof options === 'string') { | ||
options = { separator: options }; | ||
} | ||
const path = chain.split(options.separator || '.'); | ||
return (obj) => { | ||
let ref = obj; | ||
for (let i = 0; i < path.length; ++i) { | ||
let key = path[i]; | ||
if (key[0] === '-' && Array.isArray(ref)) { | ||
key = key.slice(1, key.length); | ||
key = ref.length - key; | ||
} | ||
if (!ref || | ||
!((typeof ref === 'object' || typeof ref === 'function') && key in ref) || | ||
(typeof ref !== 'object' && options.functions === false)) { // Only object and function can have properties | ||
Hoek.assert(!options.strict || i + 1 === path.length, `Missing segment ${key} in reach path ${chain}`); | ||
Hoek.assert(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', `Invalid segment ${key} in reach path ${chain}`); | ||
ref = options.default; | ||
break; | ||
} | ||
ref = ref[key]; | ||
} | ||
return ref; | ||
}; | ||
}; | ||
exports.transformer = (transform, options) => { | ||
const separator = (typeof options === 'object' && options !== null) ? (options.separator || '.') : '.'; | ||
const transformSteps = []; | ||
const keys = Object.keys(transform); | ||
for (let i = 0; i < keys.length; ++i) { | ||
const key = keys[i]; | ||
const sourcePath = transform[key]; | ||
Hoek.assert(typeof sourcePath === 'string', 'All mappings must be strings'); | ||
transformSteps.push({ | ||
path: key.split(separator), | ||
reacher: this.reacher(sourcePath, options) | ||
}); | ||
} | ||
const transformFn = (source) => { | ||
Hoek.assert(source === null || source === undefined || typeof source === 'object' || Array.isArray(source), 'Invalid source object: must be null, undefined, an object, or an array'); | ||
if (Array.isArray(source)) { | ||
const results = []; | ||
for (let i = 0; i < source.length; ++i) { | ||
results.push(transformFn(source[i])); | ||
} | ||
return results; | ||
} | ||
const result = {}; | ||
for (let i = 0; i < transformSteps.length; ++i) { | ||
const step = transformSteps[i]; | ||
const path = step.path; | ||
const reacher = step.reacher; | ||
let segment; | ||
let res = result; | ||
for (let j = 0; j < path.length - 1; ++j) { | ||
segment = path[j]; | ||
if (!res[segment]) { | ||
res[segment] = {}; | ||
} | ||
res = res[segment]; | ||
} | ||
segment = path[path.length - 1]; | ||
res[segment] = reacher(source); | ||
} | ||
return result; | ||
}; | ||
return transformFn; | ||
}; | ||
exports.auth = {}; | ||
@@ -238,62 +126,2 @@ | ||
exports.event = (emitter, name, options = {}) => { | ||
options = Hoek.applyToDefaults({ error: true, multiple: false }, options); | ||
return new Promise((resolve, reject) => { | ||
const onSuccess = (...values) => { | ||
if (options.error) { | ||
emitter.removeListener('error', onError); | ||
} | ||
if (options.multiple) { | ||
return resolve(values); | ||
} | ||
return resolve(values[0]); | ||
}; | ||
const onError = (err) => { | ||
emitter.removeListener(name, onSuccess); | ||
return reject(err); | ||
}; | ||
emitter.once(name, onSuccess); | ||
if (options.error) { | ||
emitter.once('error', onError); | ||
} | ||
}); | ||
}; | ||
exports.stream = async (stream, { cleanup, ...options } = {}) => { | ||
let cleanupFn; | ||
const finished = new Promise((resolve, reject) => { | ||
cleanupFn = Stream.finished(stream, options, (err) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
return resolve(); | ||
}); | ||
}); | ||
try { | ||
return await finished; | ||
} | ||
finally { | ||
if (cleanup) { | ||
cleanupFn(); | ||
} | ||
} | ||
}; | ||
exports.forEachAncestorRealm = (realm, fn) => { | ||
@@ -300,0 +128,0 @@ |
{ | ||
"name": "@hapipal/toys", | ||
"version": "3.2.0", | ||
"version": "4.0.0", | ||
"description": "The hapi utility toy chest", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"engines": { | ||
"node": ">=12" | ||
"node": ">=16" | ||
}, | ||
@@ -34,6 +35,6 @@ "directories": { | ||
"dependencies": { | ||
"@hapi/hoek": "^9.0.0" | ||
"@hapi/hoek": "^11.0.2" | ||
}, | ||
"peerDependencies": { | ||
"@hapi/hapi": ">=19 <22" | ||
"@hapi/hapi": ">=20 <22" | ||
}, | ||
@@ -46,6 +47,6 @@ "peerDependenciesMeta": { | ||
"devDependencies": { | ||
"@hapi/boom": "^9.0.0", | ||
"@hapi/code": "^8.0.0", | ||
"@hapi/hapi": "^20.0.0", | ||
"@hapi/lab": "^24.0.0", | ||
"@hapi/boom": "^10.0.0", | ||
"@hapi/code": "^9.0.2", | ||
"@hapi/hapi": "^21.2.1", | ||
"@hapi/lab": "^25.1.0", | ||
"coveralls": "^3.0.0", | ||
@@ -52,0 +53,0 @@ "joi": "^17.0.0" |
@@ -17,7 +17,7 @@ # toys | ||
> | ||
> Toys is intended for use with hapi v19+ and nodejs v12+ (_see v2 for lower support_). | ||
> Toys is intended for use with hapi v20+ and nodejs v16+ (_see v3 for lower support_). | ||
Toys is a collection of utilities made to reduce common boilerplate in **hapi v19+** projects, aid usage of events and streams in `async` functions (e.g. handlers and server methods), and provide versions of widely-used utilities from [Hoek](https://github.com/hapijs/hoek) optimized to perform well in hot code paths such as route handlers. | ||
Toys is a collection of utilities made to reduce common boilerplate in **hapi v20+** projects. | ||
Below is an example featuring [`Toys.auth.strategy()`](API.md#toysauthstrategyserver-name-authenticate), [`Toys.reacher()`](API.md#toysreacherchain-options), and [`Toys.withRouteDefaults()`](API.md#toyswithroutedefaultsdefaults). The [API Reference](API.md) is also filled with examples. | ||
Below is an example featuring [`Toys.auth.strategy()`](API.md#toysauthstrategyserver-name-authenticate) and [`Toys.withRouteDefaults()`](API.md#toyswithroutedefaultsdefaults). The [API Reference](API.md) is also filled with examples. | ||
@@ -46,5 +46,2 @@ ```js | ||
// Make function to efficiently index into a request to grab an authed user's name | ||
const grabAuthedUsername = Toys.reacher('auth.credentials.user.name'); | ||
// Default all route methods to "get", unless otherwise specified | ||
@@ -69,4 +66,3 @@ const defaultToGet = Toys.withRouteDefaults({ method: 'get' }); | ||
// grabAuthedUsername() is designed to be quick | ||
const username = grabAuthedUsername(request); | ||
const username = request.auth.credentials?.user?.name; | ||
@@ -73,0 +69,0 @@ return { username }; |
Sorry, the diff of this file is not supported yet
5
25%19166
-1.71%312
-10.6%78
-4.88%- Removed
Updated