import { CallHandler, ExecutionContext, NestInterceptor, OnApplicationBootstrap } from "@nestjs/common";
import { ModuleRef } from "@nestjs/core";
import { EventBus, RequestContextService } from "@vendure/core";
import { Observable } from "rxjs";
import { PluginUserRegistrationGuardOptions } from "./types";
/**
 * Since this interceptor will be registered globally it will run between every single request.
 * This means we must make sure to exit as early as possible in order to not slow down the Vendure instance.
 */
export declare class UserRegistrationInterceptor implements NestInterceptor, OnApplicationBootstrap {
    private eventBus;
    private moduleRef;
    private requestContextService;
    private options;
    private injector;
    constructor(eventBus: EventBus, moduleRef: ModuleRef, requestContextService: RequestContextService, options: PluginUserRegistrationGuardOptions);
    /** @internal */
    onApplicationBootstrap(): Promise<void>;
    /** @internal */
    private _isAllowed;
    /** @internal */
    intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>>;
}
/**
 * The UserRegistrationGuardPlugin let's you flexibly customize if and how you prevent users from registering with your Vendure instance.
 *
 * ```ts
 * import { UserRegistrationGuardPlugin } from "@danielbiegler/vendure-plugin-user-registration-guard";
 * export const config: VendureConfig = {
 *   // ...
 *   plugins: [
 *     UserRegistrationGuardPlugin.init({
 *       shop: {
 *         assert: {
 *           // AND means every single assertion must be true to allow user registration
 *           logicalOperator: "AND",
 *           functions: [ ], // Insert your assertions here
 *         },
 *       },
 *       admin: {
 *         assert: {
 *           // OR means user registration is allowed if a single assertion is true
 *           logicalOperator: "OR",
 *           functions: [ ], // You may leave this empty too
 *         },
 *       },
 *     }),
 *   ],
 * }
 * ```
 *
 * Please refer to the specific {@link PluginUserRegistrationGuardOptions} for how and what you can customize.
 *
 * ### 2. Create an assertion
 *
 * Here's an example assertion where we block customer registrations if the email ends with `example.com`:
 *
 * ```ts
 * const blockExampleDotCom: AssertFunctionShopApi = async (ctx, args) => {
 *   const isAllowed = !args.input.emailAddress.endsWith("example.com");
 *   return {
 *     isAllowed,
 *     reason: !isAllowed ? 'Failed because email ends with "example.com"' : undefined,
 *   };
 * };
 * ```
 *
 * The `reason` field is helpful for when you're subscribing to the published {@link BlockedCustomerRegistrationEvent} or {@link BlockedCreateAdministratorEvent} and want to log or understand why somebody got blocked.
 *
 * In your assertions you'll receive the [`RequestContext`](https://docs.vendure.io/reference/typescript-api/request/request-context) and the GraphQL arguments of the mutation, which by default are either [`RegisterCustomerInput`](https://docs.vendure.io/reference/graphql-api/shop/input-types#registercustomerinput) or [`CreateAdministratorInput`](https://docs.vendure.io/reference/graphql-api/admin/input-types#createadministratorinput) depending on the API type. For example, if you'd like to block IP ranges you can access the underlying [Express Request](https://docs.vendure.io/reference/typescript-api/request/request-context#req) object through the `RequestContext` .
 *
 * If you've extended your GraphQL API types you may override the TypeScript Generic to get completions in your assertion functions like so:
 *
 * ```ts
 * const example: AssertFunctionShopApi<{
 *   example: boolean;
 *   // ...
 * }> = async (ctx, args) => {
 *   return { isAllowed: args.example };
 * };
 * ```
 *
 * ### 3. Add it to the plugin
 *
 * ```ts
 * import { UserRegistrationGuardPlugin } from "@danielbiegler/vendure-plugin-user-registration-guard";
 * export const config: VendureConfig = {
 *   // ...
 *   plugins: [
 *     UserRegistrationGuardPlugin.init({
 *       shop: {
 *         assert: {
 *           logicalOperator: "AND",
 *           functions: [ blockExampleDotCom ],
 *         },
 *       },
 *       admin: {
 *         assert: {
 *           logicalOperator: "AND",
 *           functions: [],
 *         },
 *       },
 *     }),
 *   ],
 * }
 * ```
 *
 * ### 4. Try registering new customers
 *
 * ```graphql
 * mutation {
 *   registerCustomerAccount(input: {
 *     emailAddress: "example@example.com",
 *     # ...
 *   }) {
 *     __typename
 *   }
 * }
 * ```
 *
 * This user will now be blocked from registering according to our `blockExampleDotCom` assertion.
 *
 * #### Handling errors
 *
 * The plugin is non-intrusive and does not extend the API itself to avoid introducing unhandled errors in your code.
 *
 * It respects [`RegisterCustomerAccountResult`](https://docs.vendure.io/reference/graphql-api/shop/object-types#registercustomeraccountresult) being a Union, so we don't throw an error, but return a [`NativeAuthStrategyError`](https://docs.vendure.io/reference/graphql-api/shop/object-types#nativeauthstrategyerror). You may handle the error just like the other `RegisterCustomerAccountResult` types like [`PasswordValidationError`](https://docs.vendure.io/reference/graphql-api/shop/object-types#passwordvalidationerror) for example.
 *
 * In contrast, for admins we do throw the error! This is a little different because by default the [`createAdministrator`](https://docs.vendure.io/reference/graphql-api/admin/mutations#createadministrator) mutation does not return a Union with error types.
 *
 * Granted, the `NativeAuthStrategyError` is technically not correct for blocking registrations and doesn't communicate the blocking properly, but it's the only reasonable error type in the Union for a default non-api-extended Vendure instance. You might want to add some comments in your registration logic that the error means blockage.
 *
 * ### 5. Subscribe to events
 *
 * You may want to [subscribe](https://docs.vendure.io/guides/developer-guide/events/#subscribing-to-events) to the [EventBus](https://docs.vendure.io/reference/typescript-api/events/event-bus) to monitor blocked registration attempts.
 *
 * ```ts
 * this.eventBus
 *   .ofType(BlockedCustomerRegistrationEvent<MutationRegisterCustomerAccountArgs>)
 *   .subscribe(async (event) => {
 *     const rejecteds = event.assertions.filter((a) => !a.isAllowed);
 *     console.log(`Blocked customer registration! ${rejecteds.length}/${event.assertions.length} assertions failed, see reasons:`);
 *     rejecteds.forEach(r => console.log("  -", r.reason));
 *
 *     // Example output:
 *     // Blocked customer registration! 1/1 assertions failed, see reasons:
 *     //   - Failed because email ends with "example.com"
 *   });
 *
 * this.eventBus
 *   // You can even override the passed in args if you've extended your Graphql API
 *   .ofType(BlockedCreateAdministratorEvent<{ example: boolean }>).subscribe(async (event) => {
 *     event.args.example // is typed now! :)
 *   });
 * ```
 *
 * @category Plugin
 */
export declare class UserRegistrationGuardPlugin {
    /** @internal */
    static options: PluginUserRegistrationGuardOptions;
    /**
     * The static `init()` method is called with the options to configure the plugin.
     *
     * @example
     * ```ts
     * UserRegistrationGuardPlugin.init({
     *   shop: {
     *     assert: {
     *       logicalOperator: "AND",
     *       functions: [firstFunc, secondFunc],
     *     },
     *   },
     *   admin: {
     *     assert: {
     *       logicalOperator: "OR",
     *       functions: [],
     *     },
     *   },
     * }),
     * ```
     */
    static init(options: PluginUserRegistrationGuardOptions): typeof UserRegistrationGuardPlugin;
}
