Skip to content

Commit

Permalink
fix(core): Ensure setup and teardown can be overriden and maintain ho…
Browse files Browse the repository at this point in the history
…ok functionality (#2779)
  • Loading branch information
daffl authored Oct 6, 2022
1 parent 26a4b95 commit ab580cb
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 71 deletions.
1 change: 0 additions & 1 deletion packages/cli/src/commons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ export const checkPreconditions =
() =>
async <T extends FeathersBaseContext>(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.
`)
Expand Down
28 changes: 15 additions & 13 deletions packages/express/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,6 @@ export default function feathersExpress<S = any, C = any>(
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<S, C>)

Expand All @@ -138,6 +125,21 @@ export default function feathersExpress<S = any, C = any>(
}
})

// 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
Expand Down
17 changes: 16 additions & 1 deletion packages/express/test/rest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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<express.Application>)

await app.listen(4777, () => app.use('tasks', new Service()))
})

Expand Down
120 changes: 71 additions & 49 deletions packages/feathers/src/application.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -33,14 +33,6 @@ export class Feathers<Services, Settings>

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]
Expand Down Expand Up @@ -80,6 +72,76 @@ export class Feathers<Services, Settings>
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<L extends keyof Services & string>(
path: L,
service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L],
Expand Down Expand Up @@ -159,44 +221,4 @@ export class Feathers<Services, Settings>

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)
}
}
11 changes: 11 additions & 0 deletions packages/feathers/test/hooks/app.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof app> = {
setup: [
Expand Down
4 changes: 4 additions & 0 deletions packages/koa/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ export function koa<S = any, C = any>(

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' }
Expand Down
17 changes: 16 additions & 1 deletion packages/koa/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -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<Application>)

await app.listen(8465)
})

Expand Down
1 change: 0 additions & 1 deletion packages/socketio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
5 changes: 0 additions & 5 deletions packages/socketio/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit ab580cb

Please sign in to comment.