Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions packages/feathers/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
HookOptions,
FeathersService,
HookMap,
RegularHookMap
RegularHookMap,
Setup
} from './declarations';
import { enableRegularHooks } from './hooks/regular';

Expand All @@ -32,6 +33,7 @@ export class Feathers<Services, Settings> extends EventEmitter implements Feathe
};

private regularHooks: (this: any, allHooks: any) => any;
private setups: Setup<this>[] = [];

constructor () {
super();
Expand Down Expand Up @@ -106,14 +108,21 @@ export class Feathers<Services, Settings> extends EventEmitter implements Feathe
// Add all the mixins
this.mixins.forEach(fn => fn.call(this, protoService, location, serviceOptions));

// 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);
}

this.services[location] = protoService;

if (typeof protoService.setup === 'function') {
const setup = () => {
debug(`Setting up service for \`${location}\``);
return protoService.setup(this, location);
};

if (this._isSetup) {
setup(); // If we ran setup already, set this service up explicitly, this will not `await`
} else {
this.addSetup(setup);
}
}

return this;
}

Expand All @@ -139,25 +148,23 @@ export class Feathers<Services, Settings> extends EventEmitter implements Feathe
return this;
}

setup () {
let promise = Promise.resolve();
addSetup (setup: Setup<this>) {
if (this._isSetup) {
throw new Error(`Cannot add a setup step after app.setup() was called.`);
}

// Setup each service (pass the app so that they can look up other services etc.)
for (const path of Object.keys(this.services)) {
promise = promise.then(() => {
const service: any = this.service(path as any);
this.setups.push(setup);

if (typeof service.setup === 'function') {
debug(`Setting up service for \`${path}\``);
return this;
}

return service.setup(this, path);
}
});
}
setup (server?: any) {
this._isSetup = true;

return promise.then(() => {
this._isSetup = true;
return this;
});
const promise = this.setups.reduce((promise, setup) => {
return promise.then(() => setup(this, server));
}, Promise.resolve());

return promise.then(() => this);
}
}
4 changes: 4 additions & 0 deletions packages/feathers/src/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ export interface FeathersApplication<Services = any, Settings = any> {
path: L
): FeathersService<this, keyof any extends keyof Services ? Service : Services[L]>;

addSetup (setup: Setup<this>): this;

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

/**
Expand Down Expand Up @@ -361,3 +363,5 @@ export type HookMap<A, S> = {

export type HookOptions<A, S> =
HookMap<A, S> | HookFunction<A, S>[] | RegularHookMap<A, S>;

export type Setup<A = Application> = (app: A, server?: any) => void | Promise<void>;
25 changes: 25 additions & 0 deletions packages/feathers/test/application.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,31 @@ describe('Feathers application', () => {
assert.strictEqual(setupCount, 2);
});

it('app.setup calls functions passed to .addSetup', async () => {
const app = feathers();
const server = {};
let setupCount = 0;

const funcSetup = (count: number) => (appRef: typeof app, serverRef: any) => {
assert.strictEqual(setupCount++, count);
assert.strictEqual(appRef, app);
assert.strictEqual(serverRef, server);
};
const serviceSetup = (count: number) => async () => {
assert.strictEqual(setupCount++, count);
};

app.addSetup(funcSetup(0));
app.use('/first', { setup: serviceSetup(1) });
app.addSetup(funcSetup(2));
app.use('/second', { setup: serviceSetup(3) });
app.addSetup(funcSetup(4));
assert.strictEqual(setupCount, 0);

await app.setup(server);
assert.strictEqual(setupCount, 5);
});

it('registering a service after app.setup will be set up', done => {
const app = feathers();

Expand Down