import { Config } from './conf/index.js';
import type { NymphDriver } from './driver/index.js';
import Entity, { type EntityInstanceType, type EntityObjectType } from './Entity.js';
import type { EntityConstructor, EntityInterface, SerializedEntityData } from './Entity.types.js';
import type { Selector, Options, NymphConnectCallback, NymphDisconnectCallback, NymphBeforeGetEntityCallback, NymphBeforeGetEntitiesCallback, NymphBeforeSaveEntityCallback, NymphAfterSaveEntityCallback, NymphFailedSaveEntityCallback, NymphBeforeDeleteEntityCallback, NymphAfterDeleteEntityCallback, NymphFailedDeleteEntityCallback, NymphBeforeDeleteEntityByIDCallback, NymphAfterDeleteEntityByIDCallback, NymphFailedDeleteEntityByIDCallback, NymphBeforeNewUIDCallback, NymphAfterNewUIDCallback, NymphFailedNewUIDCallback, NymphBeforeSetUIDCallback, NymphAfterSetUIDCallback, NymphFailedSetUIDCallback, NymphBeforeRenameUIDCallback, NymphAfterRenameUIDCallback, NymphFailedRenameUIDCallback, NymphBeforeDeleteUIDCallback, NymphAfterDeleteUIDCallback, NymphFailedDeleteUIDCallback, NymphBeforeStartTransactionCallback, NymphAfterStartTransactionCallback, NymphBeforeCommitTransactionCallback, NymphAfterCommitTransactionCallback, NymphBeforeRollbackTransactionCallback, NymphAfterRollbackTransactionCallback, NymphEventType, NymphQueryCallback, FormattedSelector, TilmeldInterface } from './Nymph.types.js';
/**
 * An object relational mapper for Node.js.
 *
 * Written by Hunter Perrin for SciActive.
 *
 * @author Hunter Perrin <hperrin@port87.com>
 * @copyright SciActive Inc
 * @see http://nymph.io/
 */
export default class Nymph {
    /**
     * The Nymph config.
     */
    config: Config;
    /**
     * The Nymph instance that this one was cloned from, or null if it's not a
     * clone.
     */
    parent: Nymph | null;
    /**
     * The Nymph database driver.
     */
    driver: NymphDriver;
    /**
     * An optional Tilmeld user/group manager instance.
     */
    tilmeld?: TilmeldInterface;
    /**
     * A simple map of names to Entity classes.
     */
    private entityClasses;
    /**
     * The entity class for this instance of Nymph.
     */
    Entity: typeof Entity;
    private connectCallbacks;
    private disconnectCallbacks;
    private queryCallbacks;
    private beforeGetEntityCallbacks;
    private beforeGetEntitiesCallbacks;
    private beforeSaveEntityCallbacks;
    private afterSaveEntityCallbacks;
    private failedSaveEntityCallbacks;
    private beforeDeleteEntityCallbacks;
    private afterDeleteEntityCallbacks;
    private failedDeleteEntityCallbacks;
    private beforeDeleteEntityByIDCallbacks;
    private afterDeleteEntityByIDCallbacks;
    private failedDeleteEntityByIDCallbacks;
    private beforeNewUIDCallbacks;
    private afterNewUIDCallbacks;
    private failedNewUIDCallbacks;
    private beforeSetUIDCallbacks;
    private afterSetUIDCallbacks;
    private failedSetUIDCallbacks;
    private beforeRenameUIDCallbacks;
    private afterRenameUIDCallbacks;
    private failedRenameUIDCallbacks;
    private beforeDeleteUIDCallbacks;
    private afterDeleteUIDCallbacks;
    private failedDeleteUIDCallbacks;
    private beforeStartTransactionCallbacks;
    private afterStartTransactionCallbacks;
    private beforeCommitTransactionCallbacks;
    private afterCommitTransactionCallbacks;
    private beforeRollbackTransactionCallbacks;
    private afterRollbackTransactionCallbacks;
    /**
     * Initialize Nymph.
     *
     * @param config The Nymph configuration.
     * @param driver The Nymph database driver.
     * @param tilmeld The Tilmeld user/group manager instance, if you want to use it.
     * @param parent Used internally by Nymph. Don't set this.
     */
    constructor(config: Partial<Config>, driver: NymphDriver, tilmeld?: TilmeldInterface, parent?: Nymph);
    /**
     * Add your class to this instance.
     *
     * This will create a class that extends your class within this instance of
     * Nymph and return it. You can then use this class's constructor and methods,
     * which will use this instance of Nymph.
     *
     * Because this creates a subclass, don't use the class
     * returned from `getEntityClass` to check with `instanceof`.
     */
    addEntityClass<T extends EntityConstructor>(EntityClass: T): T;
    /**
     * Get the class that uses the specified class name.
     */
    getEntityClass(className: string): EntityConstructor;
    getEntityClass<T extends EntityConstructor>(className: T): T;
    /**
     * Get the class that uses the specified etype.
     *
     * Note that it is fine, though unusual, for two classes to use the same
     * etype. However, this can lead to very hard to diagnose bugs, so is
     * generally discouraged.
     */
    getEntityClassByEtype(etype: string): EntityConstructor;
    /**
     * Get a clone of this instance with cloned classes and event listeners.
     *
     * @returns A clone of this instance.
     */
    clone(): Nymph;
    /**
     * Connect to the database.
     *
     * @returns Whether the instance is connected to the database.
     */
    connect(): Promise<boolean>;
    /**
     * Disconnect from the database.
     *
     * @returns Whether the instance is connected to the database.
     */
    disconnect(): Promise<boolean>;
    /**
     * Run all the query callbacks on a query.
     */
    runQueryCallbacks(options: Options, selectors: FormattedSelector[]): void;
    /**
     * Start an atomic transaction and returns a new instance of Nymph.
     *
     * All proceeding changes using this new instance will wait to be written to
     * the database's permanent storage until commit() is called. You can also
     * undo all the changes since this function ran with rollback().
     *
     * Transactions will nest as long as every name is unique. Internally, Nymph
     * uses names prefixed with "nymph-".
     *
     * @returns A new instance of Nymph that should be used for the transaction.
     */
    startTransaction(name: string): Promise<Nymph>;
    /**
     * Commit the named transaction.
     *
     * After this is called, the transaction instance should be discarded.
     *
     * @returns True on success, false on failure.
     */
    commit(name: string): Promise<boolean>;
    /**
     * Rollback the named transaction.
     *
     * After this is called, the transaction instance should be discarded.
     *
     * @returns True on success, false on failure.
     */
    rollback(name: string): Promise<boolean>;
    /**
     * Check if there is any open transaction.
     *
     * @returns True if there is a transaction.
     */
    inTransaction(): Promise<boolean>;
    /**
     * Increment or create a unique ID and return the new value.
     *
     * Unique IDs, or UIDs are similar to GUIDs, but numeric and sequential.
     *
     * A UID can be used to identify an object when the GUID doesn't suffice. On
     * a system where a new entity is created many times per second, referring
     * to something by its GUID may be unintuitive. However, the component
     * designer is responsible for assigning UIDs to the component's entities.
     * Beware that if a UID is incremented for an entity, and the entity cannot
     * be saved, there is no safe, and therefore, no recommended way to
     * decrement the UID back to its previous value.
     *
     * If newUID() is passed the name of a UID which does not exist yet, one
     * will be created with that name, and assigned the value 1. If the UID
     * already exists, its value will be incremented. The new value will be
     * returned.
     *
     * @param name The UID's name.
     * @returns The UID's new value, or null on failure.
     */
    newUID(name: string): Promise<number | null>;
    /**
     * Get the current value of a unique ID.
     * @param name The UID's name.
     * @returns The UID's value, or null on failure and if it doesn't exist.
     */
    getUID(name: string): Promise<number | null>;
    /**
     * Set the value of a UID.
     *
     * @param name The UID's name.
     * @param value The value.
     * @returns True on success, false on failure.
     */
    setUID(name: string, value: number): Promise<boolean>;
    /**
     * Delete a unique ID.
     *
     * @param name The UID's name.
     * @returns True on success, false on failure.
     */
    deleteUID(name: string): Promise<boolean>;
    /**
     * Rename a unique ID.
     *
     * @param oldName The old name.
     * @param newName The new name.
     * @returns True on success, false on failure.
     */
    renameUID(oldName: string, newName: string): Promise<boolean>;
    /**
     * Save an entity to the database.
     *
     * If the entity has never been saved (has no GUID), a variable "cdate"
     * is set on it with the current Unix timestamp.
     *
     * The variable "mdate" is set to the current Unix timestamp.
     *
     * @param entity The entity.
     * @returns True on success, false on failure.
     */
    saveEntity(entity: EntityInterface): Promise<boolean>;
    /**
     * Get an array of entities.
     *
     * `options` is an object, which contains any of the following settings:
     *
     * - class - The class to create each entity with.
     * - limit - The limit of entities to be returned.
     * - offset - The offset from the oldest matching entity to start retrieving.
     * - reverse - If true, entities will be retrieved from newest to oldest.
     *   Therefore, offset will be from the newest entity.
     * - sort - How to sort the entities. Accepts "cdate", "mdate", the name of a
     *   top-level property, or null for no particular order. The method of
     *   sorting properties other than cdate and mdate is driver dependent. The
     *   only hard rule is that numbers should be sorted numerically (2 before
     *   10). Defaults to "cdate".
     * - return - What to return. "entity", "object", "guid", or "count". Defaults
     *   to "entity".
     * - source - Will be 'client' if the query came from a REST call.
     * - skipCache - If true, Nymph will skip the cache and retrieve the entity
     *   from the DB.
     * - skipAc - If true, Tilmeld will not filter returned entities according to
     *   access controls. (If Tilmeld is installed.) (This is *always* set to
     *   false by the REST server.)
     *
     * If a class is specified, it must have a factory() static method that
     * returns a new instance.
     *
     * Selectors are objects. Any amount of selectors can be provided. Empty
     * selectors will be ignored. The `type` property of a selector is required
     * and can be one of the following strings:
     *
     * - & - (and) All values in the selector must be true.
     * - | - (or) At least one value in the selector must be true.
     * - !& - (not and) All values in the selector must be false.
     * - !| - (not or) At least one value in the selector must be false.
     *
     * The rest of the properties in the selectors are called selector clauses,
     * which can be any of the following (in the form selector.name = value, or
     * selector.name = [value1, value2,...]):
     *
     * - guid - A GUID. True if the entity's GUID is equal.
     * - tag - A tag. True if the entity has the tag.
     * - defined - A name. True if the named property exists.
     * - truthy - A name. True if the named property is defined and truthy.
     * - equal - An array with a name, then value. True if the named property is
     *   defined and equal (their JSON strings are identical).
     * - contain - An array with a name, then value. True if the named property
     *   contains the value (its JSON string is found within the property's JSON
     *   string).
     * - search - An array with a name, then search query. True if the named
     *   property matches the query. Use single quotes to find sequential terms.
     *   Use double quotes to find exact terms. Use "or" as the or operator. Use
     *   "-" before a term as the negation operator. Stop words and punctuation
     *   are stripped. Case insensitive.
     * - match - An array with a name, then regular expression. True if the
     *   named property matches. Uses POSIX RegExp. Case sensitive. Must *not* be
     *   surrounded by any delimiters.
     * - imatch - An array with a name, then regular expression. True if the
     *   named property matches. Uses POSIX RegExp. Case insensitive. Must *not*
     *   be surrounded by any delimiters.
     * - like - An array with a name, then pattern. True if the named property
     *   matches. Uses % for variable length wildcard and _ for single character
     *   wildcard. Case sensitive.
     * - ilike - An array with a name, then pattern. True if the named property
     *   matches. Uses % for variable length wildcard and _ for single character
     *   wildcard. Case insensitive.
     * - gt - An array with a name, then value. True if the named property is
     *   greater than the value.
     * - gte - An array with a name, then value. True if the named property is
     *   greater than or equal to the value.
     * - lt - An array with a name, then value. True if the named property is
     *   less than the value.
     * - lte - An array with a name, then value. True if the named property is
     *   less than or equal to the value.
     * - ref - An array with a name, then either an entity, or a GUID. True if
     *   the named property is the entity or contains the entity.
     * - qref - An array with a name, then a full query (including options) in an
     *   array. True if the named property is an entity that matches the query or
     *   contains an entity that matches the query.
     * - selector - A selector. (Keep in mind, you can also use an array of these,
     *   just like any other clause.)
     *
     * These clauses can all be negated, by prefixing them with an exclamation
     * point, such as "!truthy" to mean falsy (or undefined).
     *
     * Any clause that accepts an array of name and value can also accept a third
     * element. If value is null and the third element is a string, the third
     * element will be used with Locutus' strtotime function to set value to a
     * relative timestamp. For example, the following selector will look for all
     * entities that were created in the last day:
     *
     * ```
     * {
     *   type: '&',
     *   gte: ['cdate', null, '-1 day']
     * }
     * ```
     *
     * Locutus' implementation: https://locutus.io/php/datetime/strtotime/
     * PHP's documentation: https://www.php.net/manual/en/function.strtotime.php
     *
     * This example will retrieve the last two entities where:
     *
     * - It has 'person' tag.
     * - spouse is defined.
     * - gender is male and lname is Smith.
     * - warnings is not an integer 0.
     * - It has 'level1' and 'level2' tags, or it has 'access1' and 'access2'
     *   tags.
     * - It has either 'employee' or 'manager' tag.
     * - name is either Clark, James, Chris, Christopher, Jake, or Jacob.
     * - If age is 22 or more, then pay is not greater than 8.
     *
     * ```
     * const entities = Nymph.getEntities(
     *   { class: Entity, reverse: true, limit: 2 },
     *   {
     *     type: '&', // all must be true
     *     tag: 'person',
     *     defined: 'spouse',
     *     equal: [
     *       ['gender', 'male'],
     *       ['lname', 'Smith']
     *     ],
     *     '!equal': ['warnings', 0]
     *   },
     *   {
     *     type: '|', // at least one of the selectors in this must match
     *     selector: [
     *       {
     *         type: '&',
     *         tag: ['level1', 'level2']
     *       },
     *       {
     *         type: '&',
     *         tag: ['access1', 'access2']
     *       }
     *     ]
     *   },
     *   {
     *     type: '|', // at least one must be true
     *     tag: ['employee', 'manager']
     *   },
     *   {
     *     type: '|',
     *     equal: [
     *       ['name', 'Clark'],
     *       ['name', 'James']
     *     ],
     *     match: [
     *       ['name', 'Chris(topher)?'],
     *       ['name', 'Ja(ke|cob)']
     *     ]
     *   },
     *   {
     *     type: '!|', // at least one must be false
     *     gte: ['age', 22],
     *     gt: ['pay', 8]
     *   }
     * );
     * ```
     *
     * @param options The options.
     * @param selectors Unlimited optional selectors to search for. If none are given, all entities are retrieved for the given options.
     * @returns An array of entities or guids, or a count.
     * @todo Use an asterisk to specify any variable.
     */
    getEntities<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'count';
    }, ...selectors: Selector[]): Promise<number>;
    getEntities<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'guid';
    }, ...selectors: Selector[]): Promise<string[]>;
    getEntities<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'object';
    }, ...selectors: Selector[]): Promise<EntityObjectType<T>[]>;
    getEntities<T extends EntityConstructor = EntityConstructor>(options?: Options<T>, ...selectors: Selector[]): Promise<EntityInstanceType<T>[]>;
    /**
     * Get the first entity to match all options/selectors.
     *
     * options and selectors are the same as in getEntities().
     *
     * This function is equivalent to setting options.limit to 1 for
     * getEntities(), except that it will return null if no entity is found.
     * getEntities() would return an empty array.
     *
     * @param options The options.
     * @param selectors Unlimited optional selectors to search for, or a single GUID. If none are given, all entities are searched for the given options.
     * @returns An entity or guid, or null on failure or nothing found, or a number.
     */
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'count';
    }, ...selectors: Selector[]): Promise<number>;
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'guid';
    }, ...selectors: Selector[]): Promise<string | null>;
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'object';
    }, ...selectors: Selector[]): Promise<EntityObjectType<T> | null>;
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T>, ...selectors: Selector[]): Promise<EntityInstanceType<T> | null>;
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'guid';
    }, guid: string): Promise<string | null>;
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T> & {
        return: 'object';
    }, guid: string): Promise<EntityObjectType<T> | null>;
    getEntity<T extends EntityConstructor = EntityConstructor>(options: Options<T>, guid: string): Promise<EntityInstanceType<T> | null>;
    /**
     * Delete an entity from the database.
     *
     * @param entity The entity.
     * @returns True on success, false on failure.
     */
    deleteEntity(entity: EntityInterface): Promise<boolean>;
    /**
     * Delete an entity from the database by its GUID.
     *
     * @param guid The entity's GUID.
     * @param className The entity's class name.
     * @returns True on success, false on failure.
     */
    deleteEntityByID(guid: string, className?: string): Promise<boolean>;
    /**
     * Export entities to a local file.
     *
     * This is the file format:
     *
     * ```
     * #nex2
     * # The above line must be the first thing in the file.
     * # Comments begin with #
     *    # And can have white space before them.
     * # This defines a UID.
     * <name/of/uid>[5]
     * <another uid>[8000]
     * # For UIDs, the name is in angle brackets (<>) and the value follows
     * # in square brackets ([]).
     * # This starts a new entity.
     * {1234abcd}<etype>[tag,list,with,commas]
     * # For entities, the GUID is in curly brackets ({}), then the etype in
     * #  angle brackets, then the comma separated tag list follows in square
     * #  brackets ([]).
     * # Properties are stored like this:
     * # propname=JSON.stringify(value)
     *     abilities=["system/admin"]
     *     groups=[]
     *     inheritAbilities=false
     *     name="admin"
     * # White space before/after "=" and at beginning/end of line is ignored.
     *         username  =     "admin"
     * {2}<etype>[tag,list]
     *     another="This is another entity."
     *     newline="\n"
     * ```
     *
     * @param filename The file to export to.
     * @returns True on success, false on failure.
     */
    export(filename: string): Promise<boolean>;
    /**
     * Export entities to the console.
     *
     * @returns True on success, false on failure.
     */
    exportPrint(): Promise<boolean>;
    /**
     * Import entities from a file.
     *
     * @param filename The file to import from.
     * @returns True on success, false on failure.
     */
    import(filename: string): Promise<boolean>;
    /**
     * Import a single entity.
     *
     * @param entity The entity data to import.
     */
    importEntity(entity: {
        guid: string;
        cdate: number;
        mdate: number;
        tags: string[];
        sdata: SerializedEntityData;
        etype: string;
    }): Promise<void>;
    /**
     * Import a single entity's tokens.
     *
     * This does not update any of the actual data, only the tokens used for full
     * text search.
     *
     * Be careful with this function, since you can overwrite existing tokens with
     * data that is out of sync. The DB _should_ prevent you from inserting tokens
     * for an entity that doesn't exist, but it _won't_ prevent you from inserting
     * tokens for properties that don't exist on an entity.
     *
     * @param entity The entity data to import.
     */
    importEntityTokens(entity: {
        guid: string;
        cdate: number;
        mdate: number;
        tags: string[];
        sdata: SerializedEntityData;
        etype: string;
    }): Promise<void>;
    /**
     * Import a single entity's Tilmeld access control properties.
     *
     * This does not update any of the other data, only the access control
     * columns.
     *
     * @param entity The entity data to import.
     */
    importEntityTilmeldAC(entity: {
        guid: string;
        cdate: number;
        mdate: number;
        tags: string[];
        sdata: SerializedEntityData;
        etype: string;
    }): Promise<void>;
    /**
     * Detect whether the database needs to be migrated.
     *
     * If not false (so, one of the string values), the database should be
     * exported with an old version of Nymph, then imported into a fresh database
     * with this version. Sometimes, a live migration can be done instead, which
     * will require no downtime. You should still export the database beforehand,
     * in case anything goes wrong.
     *
     * 'json' means the data tables are missing the JSON field, and the DB
     * **must** be exported and imported to fix it.
     *
     * 'tokens' means the FTS token tables are missing, and you can get away with
     * a live migration with `liveMigration('tokenTables')` and doing
     * `importEntityTokens(entity)` for each entity.
     *
     * 'tilmeldColumns' means the entity columns for "user", "group", and access
     * controls are missing, and you can get away with a live migration with
     * `liveMigration('tilmeldColumns')` and doing
     * `importEntityTilmeldAC(entity)` for each entity. DO NOT update to any
     * version later than 1.0.0-beta.109 before this is done, or access controls
     * WILL NOT work, and everyone will have access to every entity!
     */
    needsMigration(): Promise<false | "json" | "tokens" | "tilmeldColumns">;
    /**
     * Perform a live migration on the DB.
     *
     * A 'tokenTables' migration will simply add the missing token tables. It will
     * **not** fill them. You must use `importEntityTokens` on each entity after
     * running this to fill the token tables and enable full text search matching
     * on existing entities.
     *
     * A 'tilmeldColumns' migration will simply add the missing Tilmeld columns
     * and indexes to each entity table. It will **not** fill them, and you must
     * fill them before updating to the latest version of Nymph, or everyone will
     * be able to access every entity! You must use `importEntityTilmeldAC` on
     * each entity after running this.
     *
     * A 'tilmeldRemoveOldRows' migration will remove all of the old access
     * control rows in the data tables that are no longer used as of
     * 1.0.0-beta.110. MAKE SURE YOU HAVE RUN `importEntityTilmeldAC` ON ALL
     * ENTITIES BEFORE RUNNING THIS, OR THE DATA WILL BE IRRETRIEVABLY LOST!
     */
    liveMigration(migrationType: 'tokenTables' | 'tilmeldColumns' | 'tilmeldRemoveOldRows'): Promise<void>;
    /**
     * Returns a list of the etypes stored in the DB.
     */
    getEtypes(): Promise<string[]>;
    /**
     * Get all the indexes defined for a specific etype.
     *
     * @param etype The etype to get indexes for.
     */
    getIndexes(etype: string): Promise<{
        scope: "data" | "references" | "tokens";
        name: string;
        property: string;
    }[]>;
    /**
     * Add an index on a specific property to an etype.
     *
     * Nymph adds general indexes on etypes, but they span across all properties,
     * so they can only speed up a query so much. You can add indexes that are
     * specific to a property with this function, which will speed up queries for
     * that property. If an etype only has one or two properties, you may not need
     * a specific index, but if your etypes include many properties or properties
     * that generally contain large amounts of data, adding a specific index can
     * drastically improve the performance of your queries.
     *
     * The scope of the index will affect which queries it will speed up:
     *
     * - data: This will speed up comparisons and equality checks in queries.
     * - references: This will speed up ref and qref clauses in queries.
     * - tokens: This will speed up search clauses in queries.
     *
     * The name must be unique within the etype and scope or the existing index
     * will be overwritten.
     *
     * You do not need to add reference indexes for the "user" and "group"
     * properties, because these are already specifically indexed by Nymph.
     *
     * @param etype The etype to add the index on.
     * @param definition The definition of the index.
     */
    addIndex(etype: string, definition: {
        scope: 'data' | 'references' | 'tokens';
        name: string;
        property: string;
    }): Promise<boolean>;
    /**
     * Delete an index from an etype.
     *
     * @param etype The etype to delete the index on.
     * @param scope The scope of the index.
     * @param name The name of the index to delete.
     */
    deleteIndex(etype: string, scope: 'data' | 'references' | 'tokens', name: string): Promise<boolean>;
    on<T extends NymphEventType>(event: T, callback: T extends 'connect' ? NymphConnectCallback : T extends 'disconnect' ? NymphDisconnectCallback : T extends 'query' ? NymphQueryCallback : T extends 'beforeGetEntity' ? NymphBeforeGetEntityCallback : T extends 'beforeGetEntities' ? NymphBeforeGetEntitiesCallback : T extends 'beforeSaveEntity' ? NymphBeforeSaveEntityCallback : T extends 'afterSaveEntity' ? NymphAfterSaveEntityCallback : T extends 'failedSaveEntity' ? NymphFailedSaveEntityCallback : T extends 'beforeDeleteEntity' ? NymphBeforeDeleteEntityCallback : T extends 'afterDeleteEntity' ? NymphAfterDeleteEntityCallback : T extends 'failedDeleteEntity' ? NymphFailedDeleteEntityCallback : T extends 'beforeDeleteEntityByID' ? NymphBeforeDeleteEntityByIDCallback : T extends 'afterDeleteEntityByID' ? NymphAfterDeleteEntityByIDCallback : T extends 'failedDeleteEntityByID' ? NymphFailedDeleteEntityByIDCallback : T extends 'beforeNewUID' ? NymphBeforeNewUIDCallback : T extends 'afterNewUID' ? NymphAfterNewUIDCallback : T extends 'failedNewUID' ? NymphFailedNewUIDCallback : T extends 'beforeSetUID' ? NymphBeforeSetUIDCallback : T extends 'afterSetUID' ? NymphAfterSetUIDCallback : T extends 'failedSetUID' ? NymphFailedSetUIDCallback : T extends 'beforeRenameUID' ? NymphBeforeRenameUIDCallback : T extends 'afterRenameUID' ? NymphAfterRenameUIDCallback : T extends 'failedRenameUID' ? NymphFailedRenameUIDCallback : T extends 'beforeDeleteUID' ? NymphBeforeDeleteUIDCallback : T extends 'afterDeleteUID' ? NymphAfterDeleteUIDCallback : T extends 'failedDeleteUID' ? NymphFailedDeleteUIDCallback : T extends 'beforeStartTransaction' ? NymphBeforeStartTransactionCallback : T extends 'afterStartTransaction' ? NymphAfterStartTransactionCallback : T extends 'beforeCommitTransaction' ? NymphBeforeCommitTransactionCallback : T extends 'afterCommitTransaction' ? NymphAfterCommitTransactionCallback : T extends 'beforeRollbackTransaction' ? NymphBeforeRollbackTransactionCallback : T extends 'afterRollbackTransaction' ? NymphAfterRollbackTransactionCallback : never): () => boolean;
    off<T extends NymphEventType>(event: T, callback: T extends 'connect' ? NymphConnectCallback : T extends 'disconnect' ? NymphDisconnectCallback : T extends 'query' ? NymphQueryCallback : T extends 'beforeGetEntity' ? NymphBeforeGetEntityCallback : T extends 'beforeGetEntities' ? NymphBeforeGetEntitiesCallback : T extends 'beforeSaveEntity' ? NymphBeforeSaveEntityCallback : T extends 'afterSaveEntity' ? NymphAfterSaveEntityCallback : T extends 'failedSaveEntity' ? NymphFailedSaveEntityCallback : T extends 'beforeDeleteEntity' ? NymphBeforeDeleteEntityCallback : T extends 'afterDeleteEntity' ? NymphAfterDeleteEntityCallback : T extends 'failedDeleteEntity' ? NymphFailedDeleteEntityCallback : T extends 'beforeDeleteEntityByID' ? NymphBeforeDeleteEntityByIDCallback : T extends 'afterDeleteEntityByID' ? NymphAfterDeleteEntityByIDCallback : T extends 'failedDeleteEntityByID' ? NymphFailedDeleteEntityByIDCallback : T extends 'beforeNewUID' ? NymphBeforeNewUIDCallback : T extends 'afterNewUID' ? NymphAfterNewUIDCallback : T extends 'failedNewUID' ? NymphFailedNewUIDCallback : T extends 'beforeSetUID' ? NymphBeforeSetUIDCallback : T extends 'afterSetUID' ? NymphAfterSetUIDCallback : T extends 'failedSetUID' ? NymphFailedSetUIDCallback : T extends 'beforeRenameUID' ? NymphBeforeRenameUIDCallback : T extends 'afterRenameUID' ? NymphAfterRenameUIDCallback : T extends 'failedRenameUID' ? NymphFailedRenameUIDCallback : T extends 'beforeDeleteUID' ? NymphBeforeDeleteUIDCallback : T extends 'afterDeleteUID' ? NymphAfterDeleteUIDCallback : T extends 'failedDeleteUID' ? NymphFailedDeleteUIDCallback : T extends 'beforeStartTransaction' ? NymphBeforeStartTransactionCallback : T extends 'afterStartTransaction' ? NymphAfterStartTransactionCallback : T extends 'beforeCommitTransaction' ? NymphBeforeCommitTransactionCallback : T extends 'afterCommitTransaction' ? NymphAfterCommitTransactionCallback : T extends 'beforeRollbackTransaction' ? NymphBeforeRollbackTransactionCallback : T extends 'afterRollbackTransaction' ? NymphAfterRollbackTransactionCallback : never): boolean;
}
