Socket
Socket
Sign inDemoInstall

@feathersjs/hooks

Package Overview
Dependencies
Maintainers
4
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@feathersjs/hooks - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

deno/base.ts

18

CHANGELOG.md

@@ -6,2 +6,20 @@ # Change Log

# [0.2.0](https://github.com/feathersjs/hooks/compare/v0.1.0...v0.2.0) (2020-01-14)
### Bug Fixes
* Add tests for fn.original and update documentation ([#5](https://github.com/feathersjs/hooks/issues/5)) ([f4c1955](https://github.com/feathersjs/hooks/commit/f4c195512c2f24d4d9abb68d39275f2287574162))
### Features
* Add browser build ([#8](https://github.com/feathersjs/hooks/issues/8)) ([d6162ca](https://github.com/feathersjs/hooks/commit/d6162caccabe43c468df9360f7f03362ad36c41d))
* Add build script and publish a version for Deno ([#6](https://github.com/feathersjs/hooks/issues/6)) ([f2b5697](https://github.com/feathersjs/hooks/commit/f2b56972fa2ef21799bc6e531644ef9e751bd25b))
* Refactoring to pass an option object to initialize hooks more explicitly ([#7](https://github.com/feathersjs/hooks/issues/7)) ([8f2453f](https://github.com/feathersjs/hooks/commit/8f2453f3e230f6c17989f244cc3dc8126a895eeb))
# 0.1.0 (2020-01-05)

@@ -8,0 +26,0 @@

17

lib/base.d.ts

@@ -9,3 +9,3 @@ import { Middleware } from './compose';

export declare function registerMiddleware<T>(target: T, middleware: Middleware[]): T;
export declare function getMiddleware(target: any): Middleware[];
export declare function getMiddleware<T>(target: any): Array<Middleware<T>>;
/**

@@ -30,2 +30,17 @@ * The base hook context.

/**
* A function that for a given function, calling context and arguments returns the list of hooks
*/
export declare type MiddlewareCollector<T = any> = (self: any, fn: any, args: any[]) => Array<Middleware<T>>;
/**
* Available options when initializing hooks with more than just an array of middleware
*/
export interface FunctionHookOptions<T = any> {
middleware: Array<Middleware<T>>;
context: ContextUpdater<T>;
collect: MiddlewareCollector<T>;
}
export declare type HookSettings<T = any> = Array<Middleware<T>> | Partial<FunctionHookOptions>;
export declare function defaultCollectMiddleware<T = any>(self: any, fn: any, _args: any[]): Middleware<T>[];
export declare function normalizeOptions<T = any>(opts: HookSettings): FunctionHookOptions<T>;
/**
* Returns a ContextUpdater function that turns function arguments like

@@ -32,0 +47,0 @@ * `function (data, name)` into named properties (`context.data`, `context.name`)

@@ -28,2 +28,15 @@ "use strict";

exports.HookContext = HookContext;
function defaultCollectMiddleware(self, fn, _args) {
return [
...getMiddleware(self),
...getMiddleware(fn)
];
}
exports.defaultCollectMiddleware = defaultCollectMiddleware;
function normalizeOptions(opts) {
const options = Array.isArray(opts) ? { middleware: opts } : opts;
const { middleware = [], context = withParams(), collect = defaultCollectMiddleware } = options;
return { middleware, context, collect };
}
exports.normalizeOptions = normalizeOptions;
/**

@@ -30,0 +43,0 @@ * Returns a ContextUpdater function that turns function arguments like

5

lib/decorator.d.ts

@@ -1,3 +0,2 @@

import { Middleware } from './compose';
import { ContextUpdater } from './base';
export declare const hookDecorator: <T>(hooks: Middleware<T>[], _updateContext?: ContextUpdater<T>) => (_target: any, method: string, descriptor: TypedPropertyDescriptor<any>) => TypedPropertyDescriptor<any>;
import { HookSettings } from './base';
export declare const hookDecorator: <T>(hooks?: HookSettings<T>) => (_target: any, method: string, descriptor: TypedPropertyDescriptor<any>) => TypedPropertyDescriptor<any>;

@@ -5,9 +5,7 @@ "use strict";

const base_1 = require("./base");
exports.hookDecorator = (hooks, _updateContext) => {
exports.hookDecorator = (hooks = []) => {
return (_target, method, descriptor) => {
const options = base_1.normalizeOptions(hooks);
if (!descriptor) {
if (_updateContext) {
throw new Error('Context can not be updated at the class decorator level. Remove updateContext parameter.');
}
base_1.registerMiddleware(_target.prototype, hooks);
base_1.registerMiddleware(_target.prototype, options.middleware);
return _target;

@@ -19,9 +17,12 @@ }

}
const originalUpdateContext = _updateContext || base_1.withParams();
const updateContext = (self, args, context) => {
const ctx = originalUpdateContext(self, args, context);
const originalContext = options.context;
const context = (self, args, context) => {
const ctx = originalContext(self, args, context);
ctx.method = method;
return ctx;
};
descriptor.value = function_1.functionHooks(fn, hooks, updateContext);
descriptor.value = function_1.functionHooks(fn, {
...options,
context
});
return descriptor;

@@ -28,0 +29,0 @@ };

@@ -1,3 +0,2 @@

import { Middleware } from './compose';
import { ContextUpdater } from './base';
import { HookSettings } from './base';
/**

@@ -10,8 +9,7 @@ * Returns a new function that is wrapped in the given hooks.

*
* @param fn The function to wrap
* @param hooks The list of hooks (middleware)
* @param updateContext A ContextUpdate method
* @param original The function to wrap
* @param options A list of hooks (middleware) or options for more detailed hook processing
*/
export declare const functionHooks: <T = any>(fn: any, hooks: Middleware<T>[], updateContext?: ContextUpdater<any>) => ((this: any, ...args: any[]) => Promise<any>) & {
original: any;
export declare const functionHooks: <F, T = any>(original: F, opts: HookSettings<T>) => ((this: any, ...args: any[]) => Promise<any>) & {
original: F & Function;
};

@@ -12,11 +12,11 @@ "use strict";

*
* @param fn The function to wrap
* @param hooks The list of hooks (middleware)
* @param updateContext A ContextUpdate method
* @param original The function to wrap
* @param options A list of hooks (middleware) or options for more detailed hook processing
*/
exports.functionHooks = (fn, hooks, updateContext = base_1.withParams()) => {
if (typeof fn !== 'function') {
exports.functionHooks = (original, opts) => {
if (typeof original !== 'function') {
throw new Error('Can not apply hooks to non-function');
}
const result = base_1.registerMiddleware(function (...args) {
const { context: updateContext, collect, middleware } = base_1.normalizeOptions(opts);
const wrapper = function (...args) {
// If we got passed an existing HookContext instance, we want to return it as well

@@ -32,10 +32,8 @@ const returnContext = args[args.length - 1] instanceof base_1.HookContext;

(ctx, next) => next().then(() => returnContext ? ctx : ctx.result),
// The hooks attached to the `this` object
...base_1.getMiddleware(this),
// The hook chain attached to this function
...base_1.getMiddleware(result),
// Runs the actual original method if `ctx.result` is not set
// Create the hook chain by calling the `collectMiddleware function
...collect(this, wrapper, args),
// Runs the actual original method if `ctx.result` is not already set
(ctx, next) => {
if (ctx.result === undefined) {
return Promise.resolve(fn.apply(this, ctx.arguments)).then(result => {
return Promise.resolve(original.apply(this, ctx.arguments)).then(result => {
ctx.result = result;

@@ -49,5 +47,6 @@ return next();

return compose_1.compose(hookChain).call(this, context);
}, hooks);
return Object.assign(result, { original: fn });
};
base_1.registerMiddleware(wrapper, middleware);
return Object.assign(wrapper, { original });
};
//# sourceMappingURL=function.js.map

@@ -1,9 +0,11 @@

import { Middleware } from './compose';
import { ContextUpdater } from './base';
import { MiddlewareMap, ContextUpdaterMap } from './object';
import { HookSettings } from './base';
import { HookMap } from './object';
export * from './function';
export * from './compose';
export * from './base';
export declare function hooks<F, T = any>(fn: F, hooks: Array<Middleware<T>>, updateContext?: ContextUpdater<T>): F & ((...rest: any[]) => Promise<T>);
export declare function hooks<T>(obj: T, hookMap: MiddlewareMap, contextMap?: ContextUpdaterMap): T;
export declare function hooks<F, T = any>(hooks: Array<Middleware<T>>, updateContext?: ContextUpdater<T>): any;
export interface OriginalAddon<F> {
original: F;
}
export declare function hooks<F, T = any>(fn: F, hooks: HookSettings): F & ((...rest: any[]) => Promise<T>) & OriginalAddon<F>;
export declare function hooks<O>(obj: O, hookMap: HookMap): O;
export declare function hooks<T = any>(hooks?: HookSettings): any;

@@ -14,12 +14,12 @@ "use strict";

function hooks(...args) {
const [target, _hooks, ...rest] = args;
if (Array.isArray(_hooks) && typeof target === 'function') {
return function_1.functionHooks(target, _hooks, ...rest);
const [target, _hooks] = args;
if (typeof target === 'function' && Array.isArray(_hooks.middleware || _hooks)) {
return function_1.functionHooks(target, _hooks);
}
if (Array.isArray(target)) {
return decorator_1.hookDecorator(target, _hooks);
if (args.length === 2) {
return object_1.objectHooks(target, _hooks);
}
return object_1.objectHooks(target, _hooks, ...rest);
return decorator_1.hookDecorator(target);
}
exports.hooks = hooks;
//# sourceMappingURL=index.js.map
import { Middleware } from './compose';
import { ContextUpdater } from './base';
export interface MiddlewareMap {
[key: string]: Middleware[];
import { HookSettings } from './base';
export interface HookMap {
[key: string]: HookSettings;
}
export interface ContextUpdaterMap {
[key: string]: ContextUpdater;
}
export declare const objectHooks: (_obj: any, hooks: Middleware<any>[] | MiddlewareMap, contextMap?: ContextUpdaterMap) => any;
export declare const objectHooks: (_obj: any, hooks: HookMap | Middleware<any>[]) => any;

@@ -5,3 +5,3 @@ "use strict";

const base_1 = require("./base");
exports.objectHooks = (_obj, hooks, contextMap) => {
exports.objectHooks = (_obj, hooks) => {
const obj = typeof _obj === 'function' ? _obj.prototype : _obj;

@@ -11,9 +11,8 @@ if (Array.isArray(hooks)) {

}
const hookMap = hooks;
return Object.keys(hookMap).reduce((result, method) => {
return Object.keys(hooks).reduce((result, method) => {
const value = obj[method];
const hooks = hookMap[method];
const originalUpdateContext = (contextMap && contextMap[method]) || base_1.withParams();
const updateContext = (self, args, context) => {
const ctx = originalUpdateContext(self, args, context);
const options = base_1.normalizeOptions(hooks[method]);
const originalContext = options.context;
const context = (self, args, context) => {
const ctx = originalContext(self, args, context);
ctx.method = method;

@@ -25,3 +24,6 @@ return ctx;

}
const fn = function_1.functionHooks(value, hooks, updateContext);
const fn = function_1.functionHooks(value, {
...options,
context
});
result[method] = fn;

@@ -28,0 +30,0 @@ return result;

{
"name": "@feathersjs/hooks",
"version": "0.1.0",
"version": "0.2.0",
"description": "Async middleware for JavaScript and TypeScript",

@@ -13,3 +13,3 @@ "homepage": "https://feathersjs.com",

"type": "git",
"url": "git://github.com/feathersjs/feathers.git"
"url": "git://github.com/feathersjs/hooks.git"
},

@@ -23,3 +23,3 @@ "author": {

"bugs": {
"url": "https://github.com/feathersjs/feathers/issues"
"url": "https://github.com/feathersjs/hooks/issues"
},

@@ -32,4 +32,7 @@ "engines": {

"scripts": {
"prepublish": "npm run compile",
"build:browser": "webpack --config build/webpack.config.js",
"build:deno": "shx mkdir -p deno && node build/deno",
"compile": "shx rm -rf lib/ && tsc",
"build": "npm run compile && npm run build:deno && npm run build:browser",
"prepublish": "npm run build",
"test": "mocha --opts ../../mocha.opts --recursive test/**.test.ts test/**/*.test.ts"

@@ -52,3 +55,8 @@ },

},
"gitHead": "90cccc96bea5b83fed6312cd35e21c9623103d08"
"dependencies": {
"ts-loader": "^6.2.1",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
},
"gitHead": "c3673960bd0e8ae4aff34f12eddc560cf8ad1553"
}

@@ -18,3 +18,3 @@ import { Middleware } from './compose';

export function getMiddleware (target: any): Middleware[] {
export function getMiddleware<T> (target: any): Array<Middleware<T>> {
return (target && target[HOOKS]) || [];

@@ -43,4 +43,37 @@ }

export type ContextUpdater<T = any> = (self: any, args: any[], context: HookContext<T>) => HookContext<T>;
/**
* A function that for a given function, calling context and arguments returns the list of hooks
*/
export type MiddlewareCollector<T = any> = (self: any, fn: any, args: any[]) => Array<Middleware<T>>;
/**
* Available options when initializing hooks with more than just an array of middleware
*/
export interface FunctionHookOptions<T = any> {
middleware: Array<Middleware<T>>;
context: ContextUpdater<T>;
collect: MiddlewareCollector<T>;
}
export type HookSettings<T = any> = Array<Middleware<T>>|Partial<FunctionHookOptions>;
export function defaultCollectMiddleware<T = any> (self: any, fn: any, _args: any[]) {
return [
...getMiddleware<T>(self),
...getMiddleware(fn)
];
}
export function normalizeOptions<T = any> (opts: HookSettings): FunctionHookOptions<T> {
const options: Partial<FunctionHookOptions> = Array.isArray(opts) ? { middleware: opts } : opts;
const {
middleware = [],
context = withParams(),
collect = defaultCollectMiddleware
} = options;
return { middleware, context, collect };
}
/**
* Returns a ContextUpdater function that turns function arguments like

@@ -47,0 +80,0 @@ * `function (data, name)` into named properties (`context.data`, `context.name`)

@@ -1,14 +0,11 @@

import { Middleware } from './compose';
import { functionHooks } from './function';
import { ContextUpdater, withParams, HookContext, registerMiddleware } from './base';
import { HookContext, registerMiddleware, normalizeOptions, HookSettings } from './base';
export const hookDecorator = <T> (hooks: Array<Middleware<T>>, _updateContext?: ContextUpdater<T>) => {
export const hookDecorator = <T> (hooks: HookSettings<T> = []) => {
return (_target: any, method: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
const options = normalizeOptions(hooks);
if (!descriptor) {
if (_updateContext) {
throw new Error('Context can not be updated at the class decorator level. Remove updateContext parameter.');
}
registerMiddleware(_target.prototype, options.middleware);
registerMiddleware(_target.prototype, hooks);
return _target;

@@ -23,5 +20,5 @@ }

const originalUpdateContext = _updateContext || withParams();
const updateContext = (self: any, args: any[], context: HookContext<any>) => {
const ctx = originalUpdateContext(self, args, context);
const originalContext = options.context;
const context = (self: any, args: any[], context: HookContext<any>) => {
const ctx = originalContext(self, args, context);

@@ -33,3 +30,6 @@ ctx.method = method;

descriptor.value = functionHooks(fn, hooks, updateContext);
descriptor.value = functionHooks(fn, {
...options,
context
});

@@ -36,0 +36,0 @@ return descriptor;

import { compose, Middleware } from './compose';
import {
HookContext, ContextUpdater, withParams,
registerMiddleware, getMiddleware
} from './base';
import { HookContext, registerMiddleware, normalizeOptions, HookSettings } from './base';

@@ -14,16 +11,12 @@ /**

*
* @param fn The function to wrap
* @param hooks The list of hooks (middleware)
* @param updateContext A ContextUpdate method
* @param original The function to wrap
* @param options A list of hooks (middleware) or options for more detailed hook processing
*/
export const functionHooks = <T = any>(
fn: any,
hooks: Array<Middleware<T>>,
updateContext: ContextUpdater = withParams()
) => {
if (typeof fn !== 'function') {
export const functionHooks = <F, T = any>(original: F, opts: HookSettings<T>) => {
if (typeof original !== 'function') {
throw new Error('Can not apply hooks to non-function');
}
const result = registerMiddleware(function (this: any, ...args: any[]) {
const { context: updateContext, collect, middleware } = normalizeOptions(opts);
const wrapper = function (this: any, ...args: any[]) {
// If we got passed an existing HookContext instance, we want to return it as well

@@ -39,10 +32,8 @@ const returnContext = args[args.length - 1] instanceof HookContext;

(ctx, next) => next().then(() => returnContext ? ctx : ctx.result),
// The hooks attached to the `this` object
...getMiddleware(this),
// The hook chain attached to this function
...getMiddleware(result),
// Runs the actual original method if `ctx.result` is not set
// Create the hook chain by calling the `collectMiddleware function
...collect(this, wrapper, args),
// Runs the actual original method if `ctx.result` is not already set
(ctx, next) => {
if (ctx.result === undefined) {
return Promise.resolve(fn.apply(this, ctx.arguments)).then(result => {
return Promise.resolve(original.apply(this, ctx.arguments)).then(result => {
ctx.result = result;

@@ -59,5 +50,7 @@

return compose(hookChain).call(this, context);
}, hooks);
};
return Object.assign(result, { original: fn });
registerMiddleware(wrapper, middleware);
return Object.assign(wrapper, { original });
};
import { functionHooks } from './function';
import { Middleware } from './compose';
import { ContextUpdater } from './base';
import { objectHooks, MiddlewareMap, ContextUpdaterMap } from './object';
import { HookSettings } from './base';
import { objectHooks, HookMap } from './object';
import { hookDecorator } from './decorator';

@@ -11,28 +10,29 @@

// hooks(fn, hooks, updateContext?)
export interface OriginalAddon<F> {
original: F;
}
// hooks(fn, hookSettings)
export function hooks<F, T = any> (
fn: F,
hooks: Array<Middleware<T>>,
updateContext?: ContextUpdater<T>
): F&((...rest: any[]) => Promise<T>);
// hooks(object, methodHookMap, methodUpdateContextMap?)
export function hooks<T> (obj: T, hookMap: MiddlewareMap, contextMap?: ContextUpdaterMap): T;
// @hooks(hooks)
export function hooks<F, T = any> (
hooks: Array<Middleware<T>>,
updateContext?: ContextUpdater<T>
fn: F, hooks: HookSettings
): F&((...rest: any[]) => Promise<T>)&OriginalAddon<F>;
// hooks(object, hookMap)
export function hooks<O> (obj: O, hookMap: HookMap): O;
// @hooks(hookSettings)
export function hooks<T = any> (
hooks?: HookSettings
): any;
// Fallthrough to actual implementation
export function hooks (...args: any[]) {
const [ target, _hooks, ...rest ] = args;
const [ target, _hooks ] = args;
if (Array.isArray(_hooks) && typeof target === 'function') {
return functionHooks(target, _hooks, ...rest);
if (typeof target === 'function' && Array.isArray(_hooks.middleware || _hooks)) {
return functionHooks(target, _hooks);
}
if (Array.isArray(target)) {
return hookDecorator(target, _hooks);
if (args.length === 2) {
return objectHooks(target, _hooks);
}
return objectHooks(target, _hooks, ...rest);
return hookDecorator(target);
}
import { Middleware } from './compose';
import { functionHooks } from './function';
import { ContextUpdater, HookContext, withParams, registerMiddleware } from './base';
import { HookContext, registerMiddleware, normalizeOptions, HookSettings } from './base';
export interface MiddlewareMap {
[key: string]: Middleware[];
export interface HookMap {
[key: string]: HookSettings;
}
export interface ContextUpdaterMap {
[key: string]: ContextUpdater;
}
export const objectHooks = (_obj: any, hooks: MiddlewareMap|Middleware[], contextMap?: ContextUpdaterMap) => {
export const objectHooks = (_obj: any, hooks: HookMap|Middleware[]) => {
const obj = typeof _obj === 'function' ? _obj.prototype : _obj;

@@ -20,10 +16,8 @@

const hookMap = hooks as MiddlewareMap;
return Object.keys(hookMap).reduce((result, method) => {
return Object.keys(hooks).reduce((result, method) => {
const value = obj[method];
const hooks = hookMap[method];
const originalUpdateContext = (contextMap && contextMap[method]) || withParams();
const updateContext = (self: any, args: any[], context: HookContext<any>) => {
const ctx = originalUpdateContext(self, args, context);
const options = normalizeOptions(hooks[method]);
const originalContext = options.context;
const context = (self: any, args: any[], context: HookContext<any>) => {
const ctx = originalContext(self, args, context);

@@ -39,3 +33,6 @@ ctx.method = method;

const fn = functionHooks(value, hooks, updateContext);
const fn = functionHooks(value, {
...options,
context
});

@@ -42,0 +39,0 @@ result[method] = fn;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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