diff --git a/packages/cli/src/commons.ts b/packages/cli/src/commons.ts index 72f3e88412..ce005d471d 100644 --- a/packages/cli/src/commons.ts +++ b/packages/cli/src/commons.ts @@ -138,7 +138,6 @@ export const checkPreconditions = () => async (ctx: T) => { if (!ctx.feathers) { - console.log(ctx) throw new Error(`Can not run generator since the current folder does not appear to be a Feathers application. Either your package.json is missing or it does not have \`feathers\` property. `) diff --git a/packages/express/src/index.ts b/packages/express/src/index.ts index 49745f274d..4699da5da0 100644 --- a/packages/express/src/index.ts +++ b/packages/express/src/index.ts @@ -102,19 +102,6 @@ export default function feathersExpress( debug('Feathers application listening') return server - }, - - async teardown(server?: any) { - return feathersTeardown.call(this, server).then( - () => - new Promise((resolve, reject) => { - if (this.server) { - this.server.close((e) => (e ? reject(e) : resolve(this))) - } else { - resolve(this) - } - }) - ) } } as Application) @@ -138,6 +125,21 @@ export default function feathersExpress( } }) + // Assign teardown and setup which will also make sure that hooks are initialized + app.setup = feathersApp.setup as any + app.teardown = async function teardown(server?: any) { + return feathersTeardown.call(this, server).then( + () => + new Promise((resolve, reject) => { + if (this.server) { + this.server.close((e) => (e ? reject(e) : resolve(this))) + } else { + resolve(this) + } + }) + ) + } + app.configure(routing() as any) return app diff --git a/packages/express/test/rest.test.ts b/packages/express/test/rest.test.ts index 8a48a846c6..f6d6e7c3a4 100644 --- a/packages/express/test/rest.test.ts +++ b/packages/express/test/rest.test.ts @@ -4,7 +4,7 @@ import axios, { AxiosRequestConfig } from 'axios' import { Server } from 'http' import { Request, Response, NextFunction } from 'express' -import { feathers, HookContext, Id, Params } from '@feathersjs/feathers' +import { ApplicationHookMap, feathers, HookContext, Id, Params } from '@feathersjs/feathers' import { Service, restTests } from '@feathersjs/tests' import { BadRequest } from '@feathersjs/errors' @@ -102,6 +102,21 @@ describe('@feathersjs/express/rest provider', () => { .use('/', new Service()) .use('todo', new Service()) + app.hooks({ + setup: [ + async (context, next) => { + assert.ok(context.app) + await next() + } + ], + teardown: [ + async (context, next) => { + assert.ok(context.app) + await next() + } + ] + } as ApplicationHookMap) + await app.listen(4777, () => app.use('tasks', new Service())) }) diff --git a/packages/feathers/src/application.ts b/packages/feathers/src/application.ts index bf0c58716f..c0997d1f56 100644 --- a/packages/feathers/src/application.ts +++ b/packages/feathers/src/application.ts @@ -1,7 +1,7 @@ import version from './version' import { EventEmitter } from 'events' import { stripSlashes, createDebug } from '@feathersjs/commons' -import { hooks, middleware } from '@feathersjs/hooks' +import { HOOKS, hooks, middleware } from '@feathersjs/hooks' import { eventHook, eventMixin } from './events' import { hookMixin } from './hooks' import { wrapService, getServiceOptions, protectedMethods } from './service' @@ -33,14 +33,6 @@ export class Feathers constructor() { super() - hooks(this, { - setup: middleware().params('server').props({ - app: this - }), - teardown: middleware().params('server').props({ - app: this - }) - }) this.registerHooks = enableHooks(this) this.registerHooks({ around: [eventHook] @@ -80,6 +72,76 @@ export class Feathers return current as any } + protected _setup() { + this._isSetup = true + + 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}\``) + + return service.setup(this, path) + } + }), + Promise.resolve() + ) + .then(() => this) + } + + get setup() { + return this._setup + } + + set setup(value) { + this._setup = (value as any)[HOOKS] + ? value + : hooks( + value, + middleware().params('server').props({ + app: this + }) + ) + } + + protected _teardown() { + this._isSetup = false + + 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}\``) + + return service.teardown(this, path) + } + }), + Promise.resolve() + ) + .then(() => this) + } + + get teardown() { + return this._teardown + } + + set teardown(value) { + this._teardown = (value as any)[HOOKS] + ? value + : hooks( + value, + middleware().params('server').props({ + app: this + }) + ) + } + use( path: L, service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L], @@ -159,44 +221,4 @@ export class Feathers return this } - - setup() { - this._isSetup = true - - 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}\``) - - return service.setup(this, path) - } - }), - Promise.resolve() - ) - .then(() => this) - } - - teardown() { - this._isSetup = false - - 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}\``) - - return service.teardown(this, path) - } - }), - Promise.resolve() - ) - .then(() => this) - } } diff --git a/packages/feathers/test/hooks/app.test.ts b/packages/feathers/test/hooks/app.test.ts index 2da944343d..2ad8ca0e35 100644 --- a/packages/feathers/test/hooks/app.test.ts +++ b/packages/feathers/test/hooks/app.test.ts @@ -56,6 +56,17 @@ describe('app.hooks', () => { it('.setup and .teardown special hooks', async () => { const app = feathers() + + // Test that setup and teardown can be overwritten + const oldSetup = app.setup + app.setup = function (arg: any) { + return oldSetup.call(this, arg) + } + const oldTeardown = app.teardown + app.teardown = function (arg: any) { + return oldTeardown.call(this, arg) + } + const order: string[] = [] const hooks: ApplicationHookMap = { setup: [ diff --git a/packages/koa/src/index.ts b/packages/koa/src/index.ts index ff4424b624..8ee9a0547a 100644 --- a/packages/koa/src/index.ts +++ b/packages/koa/src/index.ts @@ -82,6 +82,10 @@ export function koa( koaQs(app as any) + // This reinitializes hooks + app.setup = feathersApp.setup as any + app.teardown = feathersApp.teardown as any + app.configure(routing() as any) app.use((ctx, next) => { ctx.feathers = { ...ctx.feathers, provider: 'rest' } diff --git a/packages/koa/test/index.test.ts b/packages/koa/test/index.test.ts index f288969910..ec39f688c5 100644 --- a/packages/koa/test/index.test.ts +++ b/packages/koa/test/index.test.ts @@ -1,7 +1,7 @@ import { strict as assert } from 'assert' import Koa from 'koa' import axios from 'axios' -import { feathers, Id } from '@feathersjs/feathers' +import { ApplicationHookMap, feathers, Id } from '@feathersjs/feathers' import { Service, restTests } from '@feathersjs/tests' import { koa, rest, Application, bodyParser, errorHandler } from '../src' @@ -41,6 +41,21 @@ describe('@feathersjs/koa', () => { methods: ['get', 'find', 'create', 'update', 'patch', 'remove', 'customMethod'] }) + app.hooks({ + setup: [ + async (context, next) => { + assert.ok(context.app) + await next() + } + ], + teardown: [ + async (context, next) => { + assert.ok(context.app) + await next() + } + ] + } as ApplicationHookMap) + await app.listen(8465) }) diff --git a/packages/socketio/package.json b/packages/socketio/package.json index 723b4c2468..80eedda270 100644 --- a/packages/socketio/package.json +++ b/packages/socketio/package.json @@ -55,7 +55,6 @@ "dependencies": { "@feathersjs/commons": "^5.0.0-pre.29", "@feathersjs/feathers": "^5.0.0-pre.29", - "@feathersjs/hooks": "^0.7.5", "@feathersjs/transport-commons": "^5.0.0-pre.29", "socket.io": "^4.5.2" }, diff --git a/packages/socketio/src/index.ts b/packages/socketio/src/index.ts index 6e894c0a5f..e392206713 100644 --- a/packages/socketio/src/index.ts +++ b/packages/socketio/src/index.ts @@ -3,7 +3,6 @@ import { Server, ServerOptions } from 'socket.io' import { createDebug } from '@feathersjs/commons' import { Application } from '@feathersjs/feathers' import { socket } from '@feathersjs/transport-commons' -import { hooks, middleware } from '@feathersjs/hooks' import { disconnect, params, authentication, FeathersSocket } from './middleware' @@ -89,10 +88,6 @@ function configureSocketio(port?: any, options?: any, config?: any) { return setup.call(this, server, ...rest) } }) - - hooks(app, { - setup: middleware().params('server').props({ app }) - }) }) app.configure(