diff --git a/README.md b/README.md index 73baf2d..ce5f201 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ These options allow you to act on behalf of the authenticated user. Typically t - `userIdProperty` (string, defaults `'id'`). Applies to `findOne`, `find`, `create`, `update`, `destroy`, `add`, `remove`, and `populate`. - When `actAsUser` is `true` this option takes effect. It defines a path into `Request.auth.credentials` to determine the acting user's id. For example, if the credentials object equals `{user: {info: {id: 17}}}` then `'user.info.id'` would grab user id `17`. See [`Hoek.reach`](https://github.com/hapijs/hoek#reachobj-chain-options), which is used to convert the string to a deep property in the hapi credentials object. + When `actAsUser` is `true` this option takes effect. It defines a path into `Request.auth.credentials` to determine the acting user's id. For example, if the credentials object equals `{user: {info: {id: 17}}}` then `'user.info.id'` would grab user id `17`. - `userUrlPrefix` (string, defaults `'/user'`). Applies to `findOne`, `update`, `destroy`, `add`, `remove`, and `populate`. diff --git a/lib/action-util.js b/lib/action-util.js index 466c8e1..b275105 100644 --- a/lib/action-util.js +++ b/lib/action-util.js @@ -1,7 +1,8 @@ 'use strict'; +const _ = require('lodash'); +const Assert = require('node:assert'); const Boom = require('@hapi/boom'); -const Hoek = require('@hapi/hoek'); const internals = {}; @@ -187,11 +188,11 @@ module.exports = (request, options) => { getUserId: () => { - Hoek.assert(options.actAsUser, 'Not currently acting as user, per `options.actAsUser`.'); - Hoek.assert(typeof options.userIdProperty === 'string', '`options.userIdProperty` must be a string.'); - Hoek.assert(request.auth.credentials, 'Unable to get user ID from credentials'); + Assert.ok(options.actAsUser, 'Not currently acting as user, per `options.actAsUser`.'); + Assert.ok(typeof options.userIdProperty === 'string', '`options.userIdProperty` must be a string.'); + Assert.ok(request.auth.credentials, 'Unable to get user ID from credentials'); - const userId = Hoek.reach(request.auth.credentials, options.userIdProperty); + const userId = _.get(request.auth.credentials, options.userIdProperty); return userId; } diff --git a/lib/index.js b/lib/index.js index 6a5a7e1..2142a58 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,8 +1,8 @@ 'use strict'; -const Call = require('@hapi/call'); const _ = require('lodash'); -const Hoek = require('@hapi/hoek'); +const Assert = require('node:assert'); +const Call = require('@hapi/call'); const Package = require('../package.json'); const internals = {}; @@ -21,18 +21,17 @@ exports.plugin = { // handlerOptions come user-defined in route definition // nothing should override these! - const thisRouteOpts = Hoek.clone(internals.defaults); - + const thisRouteOpts = _.cloneDeep(internals.defaults); // Plugin-level user-defined options - Hoek.merge(thisRouteOpts, options); + _.merge(thisRouteOpts, options); // Route-level user-defined options - Hoek.merge(thisRouteOpts, handlerOptions); + _.merge(thisRouteOpts, handlerOptions); // Route-level info (should not override plugin options & handler options) internals.setOptionsFromRouteInfo(route, thisRouteOpts); - Hoek.assert(thisRouteOpts.model, 'Unable to determine model for route ' + route.path); + Assert.ok(thisRouteOpts.model, `Unable to determine model for route ${route.path}`); //We want to allow for Model || model let Model = {}; @@ -43,7 +42,7 @@ exports.plugin = { Model = server.models(true)[capitalizedModel]; } - Hoek.assert(Model, 'Model `' + thisRouteOpts.model + '` must exist to build route.'); + Assert.ok(Model, 'Model `' + thisRouteOpts.model + '` must exist to build route.'); // Set associations now that the model is locked-down _.defaults(thisRouteOpts, { associations: Model.relationMappings }); @@ -224,7 +223,7 @@ internals.setOptionsFromRouteInfo = (route, thisRouteOpts) => { const pathInfo = internals.Router.analyze(path); const pathSegments = pathInfo.segments.length; - Hoek.assert(pathSegments <= 4, 'Number of path segments should be between 1 and 4.'); + Assert.ok(pathSegments <= 4, 'Number of path segments should be between 1 and 4.'); switch (pathSegments) { case 4: @@ -242,8 +241,8 @@ internals.setOptionsFromRouteInfo = (route, thisRouteOpts) => { internals.normalizePath = (path, thisRouteOpts) => { - Hoek.assert(typeof thisRouteOpts.userUrlPrefix === 'string' || !thisRouteOpts.userUrlPrefix, 'Option userUrlPrefix should only have a string or a falsy value.'); - Hoek.assert(typeof thisRouteOpts.userModel === 'string' || !thisRouteOpts.userModel, 'Option userModel should only have a string or a falsy value.'); + Assert.ok(typeof thisRouteOpts.userUrlPrefix === 'string' || !thisRouteOpts.userUrlPrefix, 'Option userUrlPrefix should only have a string or a falsy value.'); + Assert.ok(typeof thisRouteOpts.userModel === 'string' || !thisRouteOpts.userModel, 'Option userModel should only have a string or a falsy value.'); if (internals.pathEndsWith(path, '/count')) { thisRouteOpts._private.count = true; @@ -251,12 +250,12 @@ internals.normalizePath = (path, thisRouteOpts) => { } //use search instead of indexof so that we're only doing whole word matching - Hoek.assert(path.search(/\bcount\b/) === -1, 'Count can only appear at the end of a route path'); + Assert.ok(path.search(/\bcount\b/) === -1, 'Count can only appear at the end of a route path'); // Deal with prefix option if (thisRouteOpts.prefix) { // Prefix pattern copied from hapi's prefix validation - Hoek.assert(typeof thisRouteOpts.prefix === 'string' && thisRouteOpts.prefix.match(/^\/.+/), 'Prefix parameter should be a string following the pattern: /^\\/.+/'); + Assert.ok(typeof thisRouteOpts.prefix === 'string' && thisRouteOpts.prefix.match(/^\/.+/), 'Prefix parameter should be a string following the pattern: /^\\/.+/'); path = internals.removePrefixFromPath(path, thisRouteOpts.prefix); } @@ -326,8 +325,8 @@ internals.pathBeginsWith = (path, needle) => { internals.removePrefixFromPath = (path, prefix) => { - Hoek.assert(typeof path === 'string', 'Path parameter should be a string'); - Hoek.assert(typeof prefix === 'string', 'Prefix parameter should be a string'); + Assert.ok(typeof path === 'string', 'Path parameter should be a string'); + Assert.ok(typeof prefix === 'string', 'Prefix parameter should be a string'); // Remove trailing slashes from prefix prefix = prefix.replace(/\/+$/, ''); diff --git a/package.json b/package.json index 5127727..f73a2c5 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "rest", "crud" ], - "author": "Matt Boutet ", + "author": "Matt Boutet and contributors", "license": "MIT", "bugs": { "url": "https://github.com/hapipal/tandy/issues" @@ -33,7 +33,6 @@ "dependencies": { "@hapi/boom": "^10.0.1", "@hapi/call": "^9.0.1", - "@hapi/hoek": "^11.0.2", "joi": "^17.7.1", "lodash": "^4.17.21" }, diff --git a/test/index.js b/test/index.js index 5a35017..755cc71 100644 --- a/test/index.js +++ b/test/index.js @@ -1,11 +1,12 @@ 'use strict'; -const Lab = require('@hapi/lab'); +const _ = require('lodash'); +const Boom = require('@hapi/boom'); const Hapi = require('@hapi/hapi'); const Joi = require('joi'); -const Hoek = require('@hapi/hoek'); -const Boom = require('@hapi/boom'); +const Lab = require('@hapi/lab'); const Schwifty = require('@hapipal/schwifty'); + const Tandy = require('..'); const TestModels = require('./models'); @@ -36,7 +37,7 @@ describe('Tandy', () => { } }; - return Hoek.applyToDefaults(options, extras || {}); + return _.defaultsDeep({}, extras, options); }; const scheme = (server, options) => {