Skip to content

Commit

Permalink
feat(core): add a method to register interceptors
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondfeng committed May 3, 2020
1 parent b1ddc7b commit 4453e01
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
7 changes: 1 addition & 6 deletions packages/boot/src/booters/interceptor.booter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
// License text available at https://opensource.org/licenses/MIT

import {
BindingScope,
config,
Constructor,
createBindingFromClass,
inject,
Interceptor,
Provider,
Expand Down Expand Up @@ -59,10 +57,7 @@ export class InterceptorProviderBooter extends BaseArtifactBooter {
this.interceptors = this.classes as InterceptorProviderClass[];
for (const interceptor of this.interceptors) {
debug('Bind interceptor: %s', interceptor.name);
const binding = createBindingFromClass(interceptor, {
defaultScope: BindingScope.TRANSIENT,
});
this.app.add(binding);
const binding = this.app.interceptor(interceptor);
debug('Binding created for interceptor: %j', binding);
}
}
Expand Down
20 changes: 19 additions & 1 deletion packages/context/src/interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import assert from 'assert';
import debugFactory from 'debug';
import {Binding, BindingTemplate} from './binding';
import {bind} from './binding-decorator';
import {BindingSpec} from './binding-inspector';
import {BindingFromClassOptions, BindingSpec} from './binding-inspector';
import {sortBindingsByPhase} from './binding-sorter';
import {Context} from './context';
import {
Expand Down Expand Up @@ -345,3 +345,21 @@ export function invokeMethodWithInterceptors(
() => invocationCtx.close(),
);
}

/**
* Options for an interceptor binding
*/
export interface InterceptorBindingOptions extends BindingFromClassOptions {
/**
* Global or local interceptor
*/
global?: boolean;
/**
* Group name for a global interceptor
*/
group?: string;
/**
* Source filter for a global interceptor
*/
source?: string[];
}
55 changes: 55 additions & 0 deletions packages/core/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
// License text available at https://opensource.org/licenses/MIT

import {
asGlobalInterceptor,
Binding,
BindingAddress,
BindingFromClassOptions,
BindingKey,
BindingScope,
Constructor,
Context,
ContextTags,
createBindingFromClass,
Interceptor,
InterceptorBindingOptions,
isProviderClass,
JSONObject,
Provider,
} from '@loopback/context';
Expand Down Expand Up @@ -457,6 +464,54 @@ export class Application extends Context implements LifeCycleObserver {
return binding;
}

public interceptor(
interceptor: Interceptor | Constructor<Provider<Interceptor>>,
nameOrOptions?: string | InterceptorBindingOptions,
) {
const options = toOptions(nameOrOptions);
let group = undefined;
let source = undefined;
let global = false;
let namespace = 'interceptors';
if (typeof nameOrOptions !== 'string') {
global = !!nameOrOptions?.global;
if (global) namespace = 'globalInterceptors';
group = nameOrOptions?.group;
source = nameOrOptions?.source;
}
let binding: Binding<Interceptor>;
if (isProviderClass(interceptor as Constructor<Provider<Interceptor>>)) {
binding = createBindingFromClass(
interceptor as Constructor<Provider<Interceptor>>,
{
...options,
},
);
this.add(binding);
} else {
let key = options.key;
if (!key) {
const name = options.name ?? interceptor.name;
if (!name) {
key = BindingKey.generate<Interceptor>(namespace).key;
} else {
key = `${namespace}.${name}`;
}
}
binding = this.bind(key as BindingAddress<Interceptor>).to(
interceptor as Interceptor,
);
}
if (global) {
binding.apply(asGlobalInterceptor(group));
if (source) {
binding.tag({[ContextTags.GLOBAL_INTERCEPTOR_SOURCE]: source});
}
}

return binding;
}

/**
* Set up signals that are captured to shutdown the application
*/
Expand Down

0 comments on commit 4453e01

Please sign in to comment.