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

@feathersjs/feathers

Package Overview
Dependencies
Maintainers
4
Versions
126
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@feathersjs/feathers - npm Package Compare versions

Comparing version 5.0.0-pre.22 to 5.0.0-pre.23

lib/hooks.d.ts

12

CHANGELOG.md

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

# [5.0.0-pre.23](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.22...v5.0.0-pre.23) (2022-06-06)
### Features
* **client:** Improve client side custom method support ([#2654](https://github.com/feathersjs/feathers/issues/2654)) ([c138acf](https://github.com/feathersjs/feathers/commit/c138acf50affbe6b66177d084d3c7a3e9220f09f))
* **core:** Rename async hooks to around hooks, allow usual registration format ([#2652](https://github.com/feathersjs/feathers/issues/2652)) ([2a485a0](https://github.com/feathersjs/feathers/commit/2a485a07929184261f27437fc0fdfe5a44694834))
# [5.0.0-pre.22](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.21...v5.0.0-pre.22) (2022-05-24)

@@ -8,0 +20,0 @@

7

lib/application.d.ts
/// <reference types="node" />
import { EventEmitter } from './dependencies';
import { FeathersApplication, ServiceMixin, Service, ServiceOptions, ServiceInterface, Application, FeathersService, HookMap, ApplicationHookOptions } from './declarations';
import { EventEmitter } from 'events';
import { FeathersApplication, ServiceMixin, Service, ServiceOptions, ServiceInterface, Application, FeathersService, ApplicationHookOptions } from './declarations';
export declare class Feathers<Services, Settings> extends EventEmitter implements FeathersApplication<Services, Settings> {

@@ -10,4 +10,3 @@ services: Services;

_isSetup: boolean;
appHooks: HookMap<Application<Services, Settings>, any>;
private regularHooks;
protected registerHooks: (this: any, allHooks: any) => any;
constructor();

@@ -14,0 +13,0 @@ get<L extends keyof Settings & string>(name: L): Settings[L];

@@ -8,9 +8,11 @@ "use strict";

const version_1 = __importDefault(require("./version"));
const dependencies_1 = require("./dependencies");
const events_1 = require("./events");
const index_1 = require("./hooks/index");
const events_1 = require("events");
const commons_1 = require("@feathersjs/commons");
const hooks_1 = require("@feathersjs/hooks");
const events_2 = require("./events");
const hooks_2 = require("./hooks");
const service_1 = require("./service");
const regular_1 = require("./hooks/regular");
const debug = (0, dependencies_1.createDebug)('@feathersjs/feathers');
class Feathers extends dependencies_1.EventEmitter {
const hooks_3 = require("./hooks");
const debug = (0, commons_1.createDebug)('@feathersjs/feathers');
class Feathers extends events_1.EventEmitter {
constructor() {

@@ -20,17 +22,17 @@ super();

this.settings = {};
this.mixins = [index_1.hookMixin, events_1.eventMixin];
this.mixins = [hooks_2.hookMixin, events_2.eventMixin];
this.version = version_1.default;
this._isSetup = false;
this.appHooks = {
[dependencies_1.HOOKS]: [events_1.eventHook]
};
this.regularHooks = (0, regular_1.enableRegularHooks)(this);
(0, dependencies_1.hooks)(this, {
setup: (0, dependencies_1.middleware)().params('server').props({
(0, hooks_1.hooks)(this, {
setup: (0, hooks_1.middleware)().params('server').props({
app: this
}),
teardown: (0, dependencies_1.middleware)().params('server').props({
teardown: (0, hooks_1.middleware)().params('server').props({
app: this
})
});
this.registerHooks = (0, hooks_3.enableHooks)(this);
this.registerHooks({
around: [events_2.eventHook]
});
}

@@ -52,3 +54,3 @@ get(name) {

service(location) {
const path = ((0, dependencies_1.stripSlashes)(location) || '/');
const path = ((0, commons_1.stripSlashes)(location) || '/');
const current = this.services[path];

@@ -65,7 +67,7 @@ if (typeof current === 'undefined') {

}
const location = ((0, dependencies_1.stripSlashes)(path) || '/');
const location = ((0, commons_1.stripSlashes)(path) || '/');
const subApp = service;
const isSubApp = typeof subApp.service === 'function' && subApp.services;
if (isSubApp) {
Object.keys(subApp.services).forEach(subPath => this.use(`${location}/${subPath}`, subApp.service(subPath)));
Object.keys(subApp.services).forEach((subPath) => this.use(`${location}/${subPath}`, subApp.service(subPath)));
return this;

@@ -82,3 +84,3 @@ }

// Add all the mixins
this.mixins.forEach(fn => fn.call(this, protoService, location, serviceOptions));
this.mixins.forEach((fn) => fn.call(this, protoService, location, serviceOptions));
this.services[location] = protoService;

@@ -94,16 +96,14 @@ // If we ran setup already, set this service up explicitly, this will not `await`

const untypedMap = hookMap;
if (untypedMap.before || untypedMap.after || untypedMap.error) {
this.regularHooks(untypedMap);
if (untypedMap.before || untypedMap.after || untypedMap.error || untypedMap.around) {
// regular hooks for all service methods
this.registerHooks(untypedMap);
}
else if (untypedMap.setup || untypedMap.teardown) {
(0, dependencies_1.hooks)(this, untypedMap);
// .setup and .teardown application hooks
(0, hooks_1.hooks)(this, untypedMap);
}
else if (Array.isArray(hookMap)) {
this.appHooks[dependencies_1.HOOKS].push(...hookMap);
}
else {
const methodHookMap = hookMap;
Object.keys(methodHookMap).forEach(key => {
const methodHooks = this.appHooks[key] || [];
this.appHooks[key] = methodHooks.concat(methodHookMap[key]);
// Other registration formats are just `around` hooks
this.registerHooks({
around: untypedMap
});

@@ -115,4 +115,4 @@ }

this._isSetup = true;
return Object.keys(this.services).reduce((current, path) => current
.then(() => {
return Object.keys(this.services)
.reduce((current, path) => current.then(() => {
const service = this.service(path);

@@ -123,8 +123,9 @@ if (typeof service.setup === 'function') {

}
}), Promise.resolve()).then(() => this);
}), Promise.resolve())
.then(() => this);
}
teardown() {
this._isSetup = false;
return Object.keys(this.services).reduce((current, path) => current
.then(() => {
return Object.keys(this.services)
.reduce((current, path) => current.then(() => {
const service = this.service(path);

@@ -135,3 +136,4 @@ if (typeof service.teardown === 'function') {

}
}), Promise.resolve()).then(() => this);
}), Promise.resolve())
.then(() => this);
}

@@ -138,0 +140,0 @@ }

/// <reference types="node" />
import { EventEmitter, NextFunction, HookContext as BaseHookContext } from './dependencies';
import { EventEmitter } from 'events';
import { NextFunction, HookContext as BaseHookContext } from '@feathersjs/hooks';
declare type SelfOrArray<S> = S | S[];

@@ -59,2 +60,3 @@ declare type OptionalPick<T, K extends PropertyKey> = Pick<T, Extract<keyof T, K>>;

};
export declare type CustomMethod<T = any, R = T, P extends Params = Params> = (data: T, params?: P) => Promise<R>;
export declare type ServiceMixin<A> = (service: FeathersService<A>, path: string, options: ServiceOptions) => void;

@@ -90,6 +92,2 @@ export declare type ServiceGenericType<S> = S extends ServiceInterface<infer T> ? T : any;

/**
* Contains all registered application level hooks.
*/
appHooks: HookMap<Application<Services, Settings>, any>;
/**
* Retrieve an application setting by name

@@ -275,20 +273,23 @@ *

}
export declare type RegularHookFunction<A = Application, S = Service> = (this: S, context: HookContext<A, S>) => (Promise<HookContext<Application, S> | void> | HookContext<Application, S> | void);
export declare type Hook<A = Application, S = Service> = RegularHookFunction<A, S>;
declare type RegularHookMethodMap<A, S> = {
[L in keyof S]?: SelfOrArray<RegularHookFunction<A, S>>;
export declare type HookFunction<A = Application, S = Service> = (this: S, context: HookContext<A, S>) => Promise<HookContext<Application, S> | void> | HookContext<Application, S> | void;
export declare type Hook<A = Application, S = Service> = HookFunction<A, S>;
declare type HookMethodMap<A, S> = {
[L in keyof S]?: SelfOrArray<HookFunction<A, S>>;
} & {
all?: SelfOrArray<RegularHookFunction<A, S>>;
all?: SelfOrArray<HookFunction<A, S>>;
};
declare type RegularHookTypeMap<A, S> = SelfOrArray<RegularHookFunction<A, S>> | RegularHookMethodMap<A, S>;
export declare type RegularHookMap<A, S> = {
before?: RegularHookTypeMap<A, S>;
after?: RegularHookTypeMap<A, S>;
error?: RegularHookTypeMap<A, S>;
declare type HookTypeMap<A, S> = SelfOrArray<HookFunction<A, S>> | HookMethodMap<A, S>;
export declare type AroundHookFunction<A = Application, S = Service> = (context: HookContext<A, S>, next: NextFunction) => Promise<void>;
export declare type AroundHookMap<A, S> = {
[L in keyof S]?: AroundHookFunction<A, S>[];
} & {
all?: AroundHookFunction<A, S>[];
};
export declare type HookFunction<A = Application, S = Service> = (context: HookContext<A, S>, next: NextFunction) => Promise<void>;
export declare type HookMap<A, S> = {
[L in keyof S]?: HookFunction<A, S>[];
around?: AroundHookMap<A, S>;
before?: HookTypeMap<A, S>;
after?: HookTypeMap<A, S>;
error?: HookTypeMap<A, S>;
};
export declare type HookOptions<A, S> = HookMap<A, S> | HookFunction<A, S>[] | RegularHookMap<A, S>;
export declare type HookOptions<A, S> = AroundHookMap<A, S> | AroundHookFunction<A, S>[] | HookMap<A, S>;
export interface ApplicationHookContext<A = Application> extends BaseHookContext {

@@ -295,0 +296,0 @@ app: A;

@@ -1,4 +0,4 @@

import { NextFunction } from './dependencies';
import { NextFunction } from '@feathersjs/hooks';
import { HookContext, FeathersService } from './declarations';
export declare function eventHook(context: HookContext, next: NextFunction): Promise<void>;
export declare function eventMixin<A>(service: FeathersService<A>): FeathersService<A, import("./declarations").Service<any, Partial<any>, import("./declarations").Params<import("./declarations").Query>>>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.eventMixin = exports.eventHook = void 0;
const dependencies_1 = require("./dependencies");
const events_1 = require("events");
const service_1 = require("./service");

@@ -15,3 +15,3 @@ function eventHook(context, next) {

const results = Array.isArray(context.result) ? context.result : [context.result];
results.forEach(element => context.self.emit(context.event, element, context));
results.forEach((element) => context.self.emit(context.event, element, context));
}

@@ -22,6 +22,5 @@ });

function eventMixin(service) {
const isEmitter = typeof service.on === 'function' &&
typeof service.emit === 'function';
const isEmitter = typeof service.on === 'function' && typeof service.emit === 'function';
if (!isEmitter) {
Object.assign(service, dependencies_1.EventEmitter.prototype);
Object.assign(service, events_1.EventEmitter.prototype);
}

@@ -28,0 +27,0 @@ return service;

@@ -6,7 +6,7 @@ import version from './version';

export declare namespace feathers {
var setDebug: typeof import("@feathersjs/commons/lib/debug").setDebug;
var setDebug: typeof import("@feathersjs/commons").setDebug;
}
export { version, Feathers };
export * from './hooks/index';
export * from './hooks';
export * from './declarations';
export * from './service';

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

exports.Feathers = exports.version = exports.feathers = void 0;
const dependencies_1 = require("./dependencies");
const commons_1 = require("@feathersjs/commons");
const version_1 = __importDefault(require("./version"));

@@ -31,4 +31,4 @@ exports.version = version_1.default;

exports.feathers = feathers;
feathers.setDebug = dependencies_1.setDebug;
__exportStar(require("./hooks/index"), exports);
feathers.setDebug = commons_1.setDebug;
__exportStar(require("./hooks"), exports);
__exportStar(require("./declarations"), exports);

@@ -35,0 +35,0 @@ __exportStar(require("./service"), exports);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapService = exports.getServiceOptions = exports.getHookMethods = exports.protectedMethods = exports.defaultEventMap = exports.defaultServiceMethods = exports.defaultServiceArguments = exports.SERVICE = void 0;
const dependencies_1 = require("./dependencies");
exports.SERVICE = (0, dependencies_1.createSymbol)('@feathersjs/service');
const events_1 = require("events");
const commons_1 = require("@feathersjs/commons");
exports.SERVICE = (0, commons_1.createSymbol)('@feathersjs/service');
exports.defaultServiceArguments = {

@@ -22,16 +23,9 @@ find: ['params'],

exports.protectedMethods = Object.keys(Object.prototype)
.concat(Object.keys(dependencies_1.EventEmitter.prototype))
.concat([
'all',
'before',
'after',
'error',
'hooks',
'setup',
'teardown',
'publish'
]);
.concat(Object.keys(events_1.EventEmitter.prototype))
.concat(['all', 'around', 'before', 'after', 'error', 'hooks', 'setup', 'teardown', 'publish']);
function getHookMethods(service, options) {
const { methods } = options;
return exports.defaultServiceMethods.filter(m => typeof service[m] === 'function' && !methods.includes(m)).concat(methods);
return exports.defaultServiceMethods
.filter((m) => typeof service[m] === 'function' && !methods.includes(m))
.concat(methods);
}

@@ -44,3 +38,3 @@ exports.getHookMethods = getHookMethods;

}
const { methods = exports.defaultServiceMethods.filter(method => typeof service[method] === 'function'), events = service.events || [] } = options;
const { methods = exports.defaultServiceMethods.filter((method) => typeof service[method] === 'function'), events = service.events || [] } = options;
const { serviceEvents = Object.values(exports.defaultEventMap).concat(events) } = options;

@@ -47,0 +41,0 @@ return {

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

declare const _default: "5.0.0-pre.22";
declare const _default: "5.0.0-pre.23";
export default _default;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = '5.0.0-pre.22';
exports.default = '5.0.0-pre.23';
//# sourceMappingURL=version.js.map
{
"name": "@feathersjs/feathers",
"description": "A framework for real-time applications and REST API with JavaScript and TypeScript",
"version": "5.0.0-pre.22",
"version": "5.0.0-pre.23",
"homepage": "http://feathersjs.com",

@@ -60,4 +60,4 @@ "repository": {

"dependencies": {
"@feathersjs/commons": "^5.0.0-pre.22",
"@feathersjs/hooks": "^0.7.4",
"@feathersjs/commons": "^5.0.0-pre.23",
"@feathersjs/hooks": "^0.7.5",
"events": "^3.3.0"

@@ -67,9 +67,9 @@ },

"@types/mocha": "^9.1.1",
"@types/node": "^17.0.31",
"@types/node": "^17.0.40",
"mocha": "^10.0.0",
"shx": "^0.3.4",
"ts-node": "^10.7.0",
"typescript": "^4.6.4"
"ts-node": "^10.8.1",
"typescript": "^4.7.3"
},
"gitHead": "e452e02063e6d8943a9cae2315ab585bc4f82fb6"
"gitHead": "a60910bd730b88053ca6648337095f1ca1e3b39f"
}

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

import version from './version';
import version from './version'
import { EventEmitter } from 'events'
import { stripSlashes, createDebug } from '@feathersjs/commons'
import { hooks, middleware } from '@feathersjs/hooks'
import { eventHook, eventMixin } from './events'
import { hookMixin } from './hooks'
import { wrapService, getServiceOptions, protectedMethods } from './service'
import {
EventEmitter, stripSlashes, createDebug, HOOKS, hooks, middleware
} from './dependencies';
import { eventHook, eventMixin } from './events';
import { hookMixin } from './hooks/index';
import { wrapService, getServiceOptions, protectedMethods } from './service';
import {
FeathersApplication,

@@ -16,24 +16,22 @@ ServiceMixin,

FeathersService,
HookMap,
ApplicationHookOptions
} from './declarations';
import { enableRegularHooks } from './hooks/regular';
} from './declarations'
import { enableHooks } from './hooks'
const debug = createDebug('@feathersjs/feathers');
const debug = createDebug('@feathersjs/feathers')
export class Feathers<Services, Settings> extends EventEmitter implements FeathersApplication<Services, Settings> {
services: Services = ({} as Services);
settings: Settings = ({} as Settings);
mixins: ServiceMixin<Application<Services, Settings>>[] = [ hookMixin, eventMixin ];
version: string = version;
_isSetup = false;
appHooks: HookMap<Application<Services, Settings>, any> = {
[HOOKS]: [ (eventHook as any) ]
};
export class Feathers<Services, Settings>
extends EventEmitter
implements FeathersApplication<Services, Settings>
{
services: Services = {} as Services
settings: Settings = {} as Settings
mixins: ServiceMixin<Application<Services, Settings>>[] = [hookMixin, eventMixin]
version: string = version
_isSetup = false
private regularHooks: (this: any, allHooks: any) => any;
protected registerHooks: (this: any, allHooks: any) => any
constructor () {
super();
this.regularHooks = enableRegularHooks(this);
constructor() {
super()
hooks(this, {

@@ -46,39 +44,43 @@ setup: middleware().params('server').props({

})
});
})
this.registerHooks = enableHooks(this)
this.registerHooks({
around: [eventHook]
})
}
get<L extends keyof Settings & string> (name: L): Settings[L] {
return this.settings[name];
get<L extends keyof Settings & string>(name: L): Settings[L] {
return this.settings[name]
}
set<L extends keyof Settings & string> (name: L, value: Settings[L]) {
this.settings[name] = value;
return this;
set<L extends keyof Settings & string>(name: L, value: Settings[L]) {
this.settings[name] = value
return this
}
configure (callback: (this: this, app: this) => void) {
callback.call(this, this);
configure(callback: (this: this, app: this) => void) {
callback.call(this, this)
return this;
return this
}
defaultService (location: string): ServiceInterface {
throw new Error(`Can not find service '${location}'`);
defaultService(location: string): ServiceInterface {
throw new Error(`Can not find service '${location}'`)
}
service<L extends keyof Services & string> (
service<L extends keyof Services & string>(
location: L
): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]> {
const path = (stripSlashes(location) || '/') as L;
const current = this.services[path];
const path = (stripSlashes(location) || '/') as L
const current = this.services[path]
if (typeof current === 'undefined') {
this.use(path, this.defaultService(path) as any);
return this.service(path);
this.use(path, this.defaultService(path) as any)
return this.service(path)
}
return current as any;
return current as any
}
use<L extends keyof Services & string> (
use<L extends keyof Services & string>(
path: L,

@@ -89,93 +91,100 @@ service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L],

if (typeof path !== 'string') {
throw new Error(`'${path}' is not a valid service path.`);
throw new Error(`'${path}' is not a valid service path.`)
}
const location = (stripSlashes(path) || '/') as L;
const subApp = service as Application;
const isSubApp = typeof subApp.service === 'function' && subApp.services;
const location = (stripSlashes(path) || '/') as L
const subApp = service as Application
const isSubApp = typeof subApp.service === 'function' && subApp.services
if (isSubApp) {
Object.keys(subApp.services).forEach(subPath =>
Object.keys(subApp.services).forEach((subPath) =>
this.use(`${location}/${subPath}` as any, subApp.service(subPath) as any)
);
)
return this;
return this
}
const protoService = wrapService(location, service, options);
const serviceOptions = getServiceOptions(protoService);
const protoService = wrapService(location, service, options)
const serviceOptions = getServiceOptions(protoService)
for (const name of protectedMethods) {
if (serviceOptions.methods.includes(name)) {
throw new Error(`'${name}' on service '${location}' is not allowed as a custom method name`);
throw new Error(`'${name}' on service '${location}' is not allowed as a custom method name`)
}
}
debug(`Registering new service at \`${location}\``);
debug(`Registering new service at \`${location}\``)
// Add all the mixins
this.mixins.forEach(fn => fn.call(this, protoService, location, serviceOptions));
this.mixins.forEach((fn) => fn.call(this, protoService, location, serviceOptions))
this.services[location] = protoService;
this.services[location] = protoService
// If we ran setup already, set this service up explicitly, this will not `await`
if (this._isSetup && typeof protoService.setup === 'function') {
debug(`Setting up service for \`${location}\``);
protoService.setup(this, location);
debug(`Setting up service for \`${location}\``)
protoService.setup(this, location)
}
return this;
return this
}
hooks (hookMap: ApplicationHookOptions<this>) {
const untypedMap = hookMap as any;
hooks(hookMap: ApplicationHookOptions<this>) {
const untypedMap = hookMap as any
if (untypedMap.before || untypedMap.after || untypedMap.error) {
this.regularHooks(untypedMap);
if (untypedMap.before || untypedMap.after || untypedMap.error || untypedMap.around) {
// regular hooks for all service methods
this.registerHooks(untypedMap)
} else if (untypedMap.setup || untypedMap.teardown) {
hooks(this, untypedMap);
} else if (Array.isArray(hookMap)) {
this.appHooks[HOOKS].push(...hookMap as any);
// .setup and .teardown application hooks
hooks(this, untypedMap)
} else {
const methodHookMap = hookMap as HookMap<Application<Services, Settings>, any>;
Object.keys(methodHookMap).forEach(key => {
const methodHooks = this.appHooks[key] || [];
this.appHooks[key] = methodHooks.concat(methodHookMap[key]);
});
// Other registration formats are just `around` hooks
this.registerHooks({
around: untypedMap
})
}
return this;
return this
}
setup () {
this._isSetup = true;
setup() {
this._isSetup = true
return Object.keys(this.services).reduce((current, path) => current
.then(() => {
const service: any = this.service(path as any);
return Object.keys(this.services)
.reduce(
(current, path) =>
current.then(() => {
const service: any = this.service(path as any)
if (typeof service.setup === 'function') {
debug(`Setting up service for \`${path}\``);
if (typeof service.setup === 'function') {
debug(`Setting up service for \`${path}\``)
return service.setup(this, path);
}
}), Promise.resolve()).then(() => this);
return service.setup(this, path)
}
}),
Promise.resolve()
)
.then(() => this)
}
teardown () {
this._isSetup = false;
teardown() {
this._isSetup = false
return Object.keys(this.services).reduce((current, path) => current
.then(() => {
const service: any = this.service(path as any);
return Object.keys(this.services)
.reduce(
(current, path) =>
current.then(() => {
const service: any = this.service(path as any)
if (typeof service.teardown === 'function') {
debug(`Tearing down service for \`${path}\``);
if (typeof service.teardown === 'function') {
debug(`Tearing down service for \`${path}\``)
return service.teardown(this, path);
}
}), Promise.resolve()).then(() => this)
return service.teardown(this, path)
}
}),
Promise.resolve()
)
.then(() => this)
}
}

@@ -1,122 +0,100 @@

import {
EventEmitter, NextFunction, HookContext as BaseHookContext
} from './dependencies';
import { EventEmitter } from 'events'
import { NextFunction, HookContext as BaseHookContext } from '@feathersjs/hooks'
type SelfOrArray<S> = S | S[];
type SelfOrArray<S> = S | S[]
type OptionalPick<T, K extends PropertyKey> = Pick<T, Extract<keyof T, K>>
export type { NextFunction };
export type { NextFunction }
export interface Paginated<T> {
total: number;
limit: number;
skip: number;
data: T[];
total: number
limit: number
skip: number
data: T[]
}
export interface ServiceOptions {
events?: string[];
methods?: string[];
serviceEvents?: string[];
routeParams?: { [key: string]: any };
events?: string[]
methods?: string[]
serviceEvents?: string[]
routeParams?: { [key: string]: any }
}
export interface ServiceMethods<T = any, D = Partial<T>, P = Params> {
find (params?: P): Promise<T | T[]>;
find(params?: P): Promise<T | T[]>
get (id: Id, params?: P): Promise<T>;
get(id: Id, params?: P): Promise<T>
create (data: D, params?: P): Promise<T>;
create(data: D, params?: P): Promise<T>
update (id: NullableId, data: D, params?: P): Promise<T | T[]>;
update(id: NullableId, data: D, params?: P): Promise<T | T[]>
patch (id: NullableId, data: D, params?: P): Promise<T | T[]>;
patch(id: NullableId, data: D, params?: P): Promise<T | T[]>
remove (id: NullableId, params?: P): Promise<T | T[]>;
remove(id: NullableId, params?: P): Promise<T | T[]>
setup? (app: Application, path: string): Promise<void>;
setup?(app: Application, path: string): Promise<void>
teardown? (app: Application, path: string): Promise<void>;
teardown?(app: Application, path: string): Promise<void>
}
export interface ServiceOverloads<T = any, D = Partial<T>, P = Params> {
create? (data: D[], params?: P): Promise<T[]>;
create?(data: D[], params?: P): Promise<T[]>
update? (id: Id, data: D, params?: P): Promise<T>;
update?(id: Id, data: D, params?: P): Promise<T>
update? (id: null, data: D, params?: P): Promise<T[]>;
update?(id: null, data: D, params?: P): Promise<T[]>
patch? (id: Id, data: D, params?: P): Promise<T>;
patch?(id: Id, data: D, params?: P): Promise<T>
patch? (id: null, data: D, params?: P): Promise<T[]>;
patch?(id: null, data: D, params?: P): Promise<T[]>
remove? (id: Id, params?: P): Promise<T>;
remove?(id: Id, params?: P): Promise<T>
remove? (id: null, params?: P): Promise<T[]>;
remove?(id: null, params?: P): Promise<T[]>
}
export type Service<T = any, D = Partial<T>, P = Params> =
ServiceMethods<T, D, P> &
ServiceOverloads<T, D, P>;
export type Service<T = any, D = Partial<T>, P = Params> = ServiceMethods<T, D, P> & ServiceOverloads<T, D, P>
export type ServiceInterface<T = any, D = Partial<T>, P = Params> =
Partial<ServiceMethods<T, D, P>>;
export type ServiceInterface<T = any, D = Partial<T>, P = Params> = Partial<ServiceMethods<T, D, P>>
export interface ServiceAddons<A = Application, S = Service> extends EventEmitter {
id?: string;
hooks (options: HookOptions<A, S>): this;
id?: string
hooks(options: HookOptions<A, S>): this
}
export interface ServiceHookOverloads<S, P = Params> {
find (
params: P,
context: HookContext
): Promise<HookContext>;
find(params: P, context: HookContext): Promise<HookContext>
get (
id: Id,
params: P,
context: HookContext
): Promise<HookContext>;
get(id: Id, params: P, context: HookContext): Promise<HookContext>
create (
create(
data: ServiceGenericData<S> | ServiceGenericData<S>[],
params: P,
context: HookContext
): Promise<HookContext>;
): Promise<HookContext>
update (
id: NullableId,
data: ServiceGenericData<S>,
params: P,
context: HookContext
): Promise<HookContext>;
update(id: NullableId, data: ServiceGenericData<S>, params: P, context: HookContext): Promise<HookContext>
patch (
id: NullableId,
data: ServiceGenericData<S>,
params: P,
context: HookContext
): Promise<HookContext>;
patch(id: NullableId, data: ServiceGenericData<S>, params: P, context: HookContext): Promise<HookContext>
remove (
id: NullableId,
params: P,
context: HookContext
): Promise<HookContext>;
remove(id: NullableId, params: P, context: HookContext): Promise<HookContext>
}
export type FeathersService<A = FeathersApplication, S = Service> =
S & ServiceAddons<A, S> & OptionalPick<ServiceHookOverloads<S>, keyof S>;
export type FeathersService<A = FeathersApplication, S = Service> = S &
ServiceAddons<A, S> &
OptionalPick<ServiceHookOverloads<S>, keyof S>
export type CustomMethods<T extends {[key: string]: [any, any]}> = {
[K in keyof T]: (data: T[K][0], params?: Params) => Promise<T[K][1]>;
export type CustomMethods<T extends { [key: string]: [any, any] }> = {
[K in keyof T]: (data: T[K][0], params?: Params) => Promise<T[K][1]>
}
export type ServiceMixin<A> = (service: FeathersService<A>, path: string, options: ServiceOptions) => void;
export type CustomMethod<T = any, R = T, P extends Params = Params> = (data: T, params?: P) => Promise<R>
export type ServiceGenericType<S> = S extends ServiceInterface<infer T> ? T : any;
export type ServiceGenericData<S> = S extends ServiceInterface<infer _T, infer D> ? D : any;
export type ServiceGenericParams<S> = S extends ServiceInterface<infer _T, infer _D, infer P> ? P : any;
export type ServiceMixin<A> = (service: FeathersService<A>, path: string, options: ServiceOptions) => void
export type ServiceGenericType<S> = S extends ServiceInterface<infer T> ? T : any
export type ServiceGenericData<S> = S extends ServiceInterface<infer _T, infer D> ? D : any
export type ServiceGenericParams<S> = S extends ServiceInterface<infer _T, infer _D, infer P> ? P : any
export interface FeathersApplication<Services = any, Settings = any> {

@@ -126,3 +104,3 @@ /**

*/
version: string;
version: string

@@ -132,3 +110,3 @@ /**

*/
mixins: ServiceMixin<Application<Services, Settings>>[];
mixins: ServiceMixin<Application<Services, Settings>>[]

@@ -141,3 +119,3 @@ /**

*/
services: Services;
services: Services

@@ -148,3 +126,3 @@ /**

*/
settings: Settings;
settings: Settings

@@ -154,10 +132,5 @@ /**

*/
_isSetup: boolean;
_isSetup: boolean
/**
* Contains all registered application level hooks.
*/
appHooks: HookMap<Application<Services, Settings>, any>;
/**
* Retrieve an application setting by name

@@ -167,3 +140,3 @@ *

*/
get<L extends keyof Settings & string> (name: L): Settings[L];
get<L extends keyof Settings & string>(name: L): Settings[L]

@@ -176,3 +149,3 @@ /**

*/
set<L extends keyof Settings & string> (name: L, value: Settings[L]): this;
set<L extends keyof Settings & string>(name: L, value: Settings[L]): this

@@ -184,3 +157,3 @@ /**

*/
configure (callback: (this: this, app: this) => void): this;
configure(callback: (this: this, app: this) => void): this

@@ -194,3 +167,3 @@ /**

*/
defaultService (location: string): ServiceInterface;
defaultService(location: string): ServiceInterface

@@ -207,7 +180,7 @@ /**

*/
use<L extends keyof Services & string> (
use<L extends keyof Services & string>(
path: L,
service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L],
options?: ServiceOptions
): this;
): this

@@ -221,5 +194,5 @@ /**

*/
service<L extends keyof Services & string> (
service<L extends keyof Services & string>(
path: L
): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]>;
): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]>

@@ -231,3 +204,3 @@ /**

*/
setup (server?: any): Promise<this>;
setup(server?: any): Promise<this>

@@ -239,3 +212,3 @@ /**

*/
teardown (server?: any): Promise<this>;
teardown(server?: any): Promise<this>

@@ -247,3 +220,3 @@ /**

*/
hooks (map: ApplicationHookOptions<this>): this;
hooks(map: ApplicationHookOptions<this>): this
}

@@ -253,18 +226,18 @@

// so that the declaration can be extended by other modules
export interface Application<Services = any, Settings = any> extends FeathersApplication<Services, Settings>, EventEmitter {
export interface Application<Services = any, Settings = any>
extends FeathersApplication<Services, Settings>,
EventEmitter {}
}
export type Id = number | string
export type NullableId = Id | null
export type Id = number | string;
export type NullableId = Id | null;
export interface Query {
[key: string]: any;
[key: string]: any
}
export interface Params<Q = Query> {
query?: Q;
provider?: string;
route?: { [key: string]: any };
headers?: { [key: string]: any };
query?: Q
provider?: string
route?: { [key: string]: any }
headers?: { [key: string]: any }
}

@@ -276,11 +249,11 @@

*/
status?: number;
status?: number
/**
* A writeable, optional property with headers.
*/
headers?: { [key: string]: string | string[] };
headers?: { [key: string]: string | string[] }
/**
* A writeable, optional property with `Location` header's value.
*/
location?: string;
location?: string
}

@@ -293,3 +266,3 @@

*/
readonly app: A;
readonly app: A
/**

@@ -299,3 +272,3 @@ * A read only property with the name of the service method (one of find, get,

*/
readonly method: string;
readonly method: string
/**

@@ -305,7 +278,7 @@ * A read only property and contains the service name (or path) without leading or

*/
readonly path: string;
readonly path: string
/**
* A read only property and contains the service this hook currently runs on.
*/
readonly service: S;
readonly service: S
/**

@@ -315,3 +288,3 @@ * A read only property with the hook type (one of before, after or error).

*/
readonly type: null | 'before' | 'after' | 'error';
readonly type: null | 'before' | 'after' | 'error'
/**

@@ -321,3 +294,3 @@ * The list of method arguments. Should not be modified, modify the

*/
readonly arguments: any[];
readonly arguments: any[]
/**

@@ -327,3 +300,3 @@ * A writeable property containing the data of a create, update and patch service

*/
data?: ServiceGenericData<S>;
data?: ServiceGenericData<S>
/**

@@ -333,3 +306,3 @@ * A writeable property with the error object that was thrown in a failed method call.

*/
error?: any;
error?: any
/**

@@ -340,3 +313,3 @@ * A writeable property and the id for a get, remove, update and patch service

*/
id?: Id;
id?: Id
/**

@@ -346,3 +319,3 @@ * A writeable property that contains the service method parameters (including

*/
params: ServiceGenericParams<S>;
params: ServiceGenericParams<S>
/**

@@ -357,3 +330,3 @@ * A writeable property containing the result of the successful service method call.

*/
result?: ServiceGenericType<S>;
result?: ServiceGenericType<S>
/**

@@ -364,3 +337,3 @@ * A writeable, optional property and contains a 'safe' version of the data that

*/
dispatch?: ServiceGenericType<S>;
dispatch?: ServiceGenericType<S>
/**

@@ -372,53 +345,58 @@ * A writeable, optional property that allows to override the standard HTTP status

*/
statusCode?: number;
statusCode?: number
/**
* A writeable, optional property with options specific to HTTP transports.
*/
http?: Http;
http?: Http
/**
* The event emitted by this method. Can be set to `null` to skip event emitting.
*/
event: string|null;
event: string | null
}
// Regular hook typings
export type RegularHookFunction<A = Application, S = Service> =
(this: S, context: HookContext<A, S>) => (Promise<HookContext<Application, S> | void> | HookContext<Application, S> | void);
export type HookFunction<A = Application, S = Service> = (
this: S,
context: HookContext<A, S>
) => Promise<HookContext<Application, S> | void> | HookContext<Application, S> | void
export type Hook<A = Application, S = Service> = RegularHookFunction<A, S>;
export type Hook<A = Application, S = Service> = HookFunction<A, S>
type RegularHookMethodMap<A, S> =
{ [L in keyof S]?: SelfOrArray<RegularHookFunction<A, S>>; } &
{ all?: SelfOrArray<RegularHookFunction<A, S>> };
type HookMethodMap<A, S> = {
[L in keyof S]?: SelfOrArray<HookFunction<A, S>>
} & { all?: SelfOrArray<HookFunction<A, S>> }
type RegularHookTypeMap<A, S> =
SelfOrArray<RegularHookFunction<A, S>> | RegularHookMethodMap<A, S>;
type HookTypeMap<A, S> = SelfOrArray<HookFunction<A, S>> | HookMethodMap<A, S>
export type RegularHookMap<A, S> = {
before?: RegularHookTypeMap<A, S>,
after?: RegularHookTypeMap<A, S>,
error?: RegularHookTypeMap<A, S>
}
// New @feathersjs/hook typings
export type HookFunction<A = Application, S = Service> =
(context: HookContext<A, S>, next: NextFunction) => Promise<void>;
export type AroundHookFunction<A = Application, S = Service> = (
context: HookContext<A, S>,
next: NextFunction
) => Promise<void>
export type AroundHookMap<A, S> = {
[L in keyof S]?: AroundHookFunction<A, S>[]
} & { all?: AroundHookFunction<A, S>[] }
export type HookMap<A, S> = {
[L in keyof S]?: HookFunction<A, S>[];
};
around?: AroundHookMap<A, S>
before?: HookTypeMap<A, S>
after?: HookTypeMap<A, S>
error?: HookTypeMap<A, S>
}
export type HookOptions<A, S> =
HookMap<A, S> | HookFunction<A, S>[] | RegularHookMap<A, S>;
export type HookOptions<A, S> = AroundHookMap<A, S> | AroundHookFunction<A, S>[] | HookMap<A, S>
export interface ApplicationHookContext<A = Application> extends BaseHookContext {
app: A;
server: any;
app: A
server: any
}
export type ApplicationHookFunction<A> =
(context: ApplicationHookContext<A>, next: NextFunction) => Promise<void>;
export type ApplicationHookFunction<A> = (
context: ApplicationHookContext<A>,
next: NextFunction
) => Promise<void>
export type ApplicationHookMap<A> = {
setup?: ApplicationHookFunction<A>[],
setup?: ApplicationHookFunction<A>[]
teardown?: ApplicationHookFunction<A>[]

@@ -425,0 +403,0 @@ }

@@ -1,10 +0,11 @@

import { NextFunction, EventEmitter } from './dependencies';
import { HookContext, FeathersService } from './declarations';
import { getServiceOptions, defaultEventMap } from './service';
import { EventEmitter } from 'events'
import { NextFunction } from '@feathersjs/hooks'
import { HookContext, FeathersService } from './declarations'
import { getServiceOptions, defaultEventMap } from './service'
export function eventHook (context: HookContext, next: NextFunction) {
const { events } = getServiceOptions((context as any).self);
const defaultEvent = (defaultEventMap as any)[context.method] || null;
export function eventHook(context: HookContext, next: NextFunction) {
const { events } = getServiceOptions((context as any).self)
const defaultEvent = (defaultEventMap as any)[context.method] || null
context.event = defaultEvent;
context.event = defaultEvent

@@ -15,18 +16,17 @@ return next().then(() => {

if (typeof context.event === 'string' && !events.includes(context.event)) {
const results = Array.isArray(context.result) ? context.result : [ context.result ];
const results = Array.isArray(context.result) ? context.result : [context.result]
results.forEach(element => (context as any).self.emit(context.event, element, context));
results.forEach((element) => (context as any).self.emit(context.event, element, context))
}
});
})
}
export function eventMixin<A> (service: FeathersService<A>) {
const isEmitter = typeof service.on === 'function' &&
typeof service.emit === 'function';
export function eventMixin<A>(service: FeathersService<A>) {
const isEmitter = typeof service.on === 'function' && typeof service.emit === 'function'
if (!isEmitter) {
Object.assign(service, EventEmitter.prototype);
Object.assign(service, EventEmitter.prototype)
}
return service;
return service
}

@@ -1,19 +0,20 @@

import { setDebug } from './dependencies';
import version from './version';
import { Feathers } from './application';
import { Application } from './declarations';
import { setDebug } from '@feathersjs/commons'
export function feathers<T = any, S = any> () {
return new Feathers<T, S>() as Application<T, S>;
import version from './version'
import { Feathers } from './application'
import { Application } from './declarations'
export function feathers<T = any, S = any>() {
return new Feathers<T, S>() as Application<T, S>
}
feathers.setDebug = setDebug;
feathers.setDebug = setDebug
export { version, Feathers };
export * from './hooks/index';
export * from './declarations';
export * from './service';
export { version, Feathers }
export * from './hooks'
export * from './declarations'
export * from './service'
if (typeof module !== 'undefined') {
module.exports = Object.assign(feathers, module.exports);
module.exports = Object.assign(feathers, module.exports)
}

@@ -1,16 +0,17 @@

import { createSymbol, EventEmitter } from './dependencies';
import { ServiceOptions } from './declarations';
import { EventEmitter } from 'events'
import { createSymbol } from '@feathersjs/commons'
import { ServiceOptions } from './declarations'
export const SERVICE = createSymbol('@feathersjs/service');
export const SERVICE = createSymbol('@feathersjs/service')
export const defaultServiceArguments = {
find: [ 'params' ],
get: [ 'id', 'params' ],
create: [ 'data', 'params' ],
update: [ 'id', 'data', 'params' ],
patch: [ 'id', 'data', 'params' ],
remove: [ 'id', 'params' ]
find: ['params'],
get: ['id', 'params'],
create: ['data', 'params'],
update: ['id', 'data', 'params'],
patch: ['id', 'data', 'params'],
remove: ['id', 'params']
}
export const defaultServiceMethods = Object.keys(defaultServiceArguments);
export const defaultServiceMethods = Object.keys(defaultServiceArguments)

@@ -26,39 +27,24 @@ export const defaultEventMap = {

.concat(Object.keys(EventEmitter.prototype))
.concat([
'all',
'before',
'after',
'error',
'hooks',
'setup',
'teardown',
'publish'
]);
.concat(['all', 'around', 'before', 'after', 'error', 'hooks', 'setup', 'teardown', 'publish'])
export function getHookMethods (service: any, options: ServiceOptions) {
const { methods } = options;
export function getHookMethods(service: any, options: ServiceOptions) {
const { methods } = options
return defaultServiceMethods.filter(m =>
typeof service[m] === 'function' && !methods.includes(m)
).concat(methods);
return defaultServiceMethods
.filter((m) => typeof service[m] === 'function' && !methods.includes(m))
.concat(methods)
}
export function getServiceOptions (
service: any, options: ServiceOptions = {}
): ServiceOptions {
const existingOptions = service[SERVICE];
export function getServiceOptions(service: any, options: ServiceOptions = {}): ServiceOptions {
const existingOptions = service[SERVICE]
if (existingOptions) {
return existingOptions;
return existingOptions
}
const {
methods = defaultServiceMethods.filter(method =>
typeof service[method] === 'function'
),
methods = defaultServiceMethods.filter((method) => typeof service[method] === 'function'),
events = service.events || []
} = options;
const {
serviceEvents = Object.values(defaultEventMap).concat(events)
} = options;
} = options
const { serviceEvents = Object.values(defaultEventMap).concat(events) } = options

@@ -70,18 +56,16 @@ return {

serviceEvents
};
}
}
export function wrapService (
location: string, service: any, options: ServiceOptions
) {
export function wrapService(location: string, service: any, options: ServiceOptions) {
// Do nothing if this is already an initialized
if (service[SERVICE]) {
return service;
return service
}
const protoService = Object.create(service);
const serviceOptions = getServiceOptions(service, options);
const protoService = Object.create(service)
const serviceOptions = getServiceOptions(service, options)
if (Object.keys(serviceOptions.methods).length === 0 && typeof service.setup !== 'function') {
throw new Error(`Invalid service object passed for path \`${location}\``);
throw new Error(`Invalid service object passed for path \`${location}\``)
}

@@ -91,5 +75,5 @@

value: serviceOptions
});
})
return protoService;
return protoService
}

@@ -1,1 +0,1 @@

export default '5.0.0-pre.22';
export default '5.0.0-pre.23';

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