@feathersjs/hooks
Version:
Async middleware for JavaScript and TypeScript
206 lines (205 loc) • 6.49 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setMiddleware = exports.getMiddleware = exports.setManager = exports.getManager = exports.convertOptions = exports.HookManager = exports.BaseHookContext = exports.HOOKS = void 0;
const utils_js_1 = require("./utils.js");
exports.HOOKS = Symbol.for('@feathersjs/hooks');
/**
* The base hook context.
*/
class BaseHookContext {
constructor(data = {}) {
Object.defineProperty(this, "self", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.assign(this, data);
}
toJSON() {
const keys = Object.keys(this);
let proto = Object.getPrototypeOf(this);
while (proto) {
keys.push(...Object.keys(proto));
proto = Object.getPrototypeOf(proto);
}
return keys.reduce((result, key) => {
result[key] = this[key];
return result;
}, {});
}
}
exports.BaseHookContext = BaseHookContext;
class HookManager {
constructor() {
Object.defineProperty(this, "_parent", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_params", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_middleware", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_props", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "_defaults", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
}
parent(parent) {
this._parent = parent;
return this;
}
middleware(middleware) {
this._middleware = middleware?.length ? middleware : null;
return this;
}
getMiddleware() {
const previous = this._parent?.getMiddleware();
if (previous && this._middleware) {
return previous.concat(this._middleware);
}
return previous || this._middleware;
}
collectMiddleware(self, _args) {
const otherMiddleware = getMiddleware(self);
const middleware = this.getMiddleware();
if (otherMiddleware && middleware) {
return otherMiddleware.concat(middleware);
}
return otherMiddleware || middleware || [];
}
props(props) {
if (!this._props) {
this._props = {};
}
(0, utils_js_1.copyProperties)(this._props, props);
return this;
}
getProps() {
const previous = this._parent?.getProps();
if (previous && this._props) {
return (0, utils_js_1.copyProperties)({}, previous, this._props);
}
return previous || this._props || null;
}
params(...params) {
this._params = params;
return this;
}
getParams() {
const previous = this._parent?.getParams();
if (previous && this._params) {
return previous.concat(this._params);
}
return previous || this._params;
}
defaults(defaults) {
this._defaults = defaults;
return this;
}
getDefaults(self, args, context) {
const defaults = typeof this._defaults === 'function'
? this._defaults(self, args, context)
: null;
const previous = this._parent?.getDefaults(self, args, context);
if (previous && defaults) {
return Object.assign({}, previous, defaults);
}
return previous || defaults;
}
getContextClass(Base = BaseHookContext) {
const ContextClass = class ContextClass extends Base {
constructor(data) {
super(data);
}
};
const params = this.getParams();
const props = this.getProps();
if (params) {
params.forEach((name, index) => {
if (props?.[name] !== undefined) {
throw new Error(`Hooks can not have a property and param named '${name}'. Use .defaults instead.`);
}
Object.defineProperty(ContextClass.prototype, name, {
enumerable: true,
get() {
return this?.arguments[index];
},
set(value) {
this.arguments[index] = value;
}
});
});
}
if (props) {
(0, utils_js_1.copyProperties)(ContextClass.prototype, props);
}
return ContextClass;
}
initializeContext(self, args, context) {
const ctx = this._parent
? this._parent.initializeContext(self, args, context)
: context;
const defaults = this.getDefaults(self, args, ctx);
if (self) {
ctx.self = self;
}
ctx.arguments = args;
if (defaults) {
for (const name of Object.keys(defaults)) {
if (ctx[name] === undefined) {
ctx[name] = defaults[name];
}
}
}
return ctx;
}
}
exports.HookManager = HookManager;
function convertOptions(options = null) {
if (!options) {
return new HookManager();
}
return Array.isArray(options)
? new HookManager().middleware(options)
: options;
}
exports.convertOptions = convertOptions;
function getManager(target) {
return (target && target[exports.HOOKS]) || null;
}
exports.getManager = getManager;
function setManager(target, manager) {
const parent = getManager(target);
target[exports.HOOKS] = manager.parent(parent);
return target;
}
exports.setManager = setManager;
function getMiddleware(target) {
const manager = getManager(target);
return manager ? manager.getMiddleware() : null;
}
exports.getMiddleware = getMiddleware;
function setMiddleware(target, middleware) {
const manager = new HookManager().middleware(middleware);
return setManager(target, manager);
}
exports.setMiddleware = setMiddleware;