var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });

// src/engine/exceptions.ts
var NotImplementedAdapterException = class _NotImplementedAdapterException extends Error {
  static {
    __name(this, "NotImplementedAdapterException");
  }
  constructor(methodName) {
    super(`Method ${methodName} was not implemented in your Adapter, it should be in order to fully work.`);
    this.name = _NotImplementedAdapterException.name;
  }
};

// src/engine/index.ts
function databaseAdapter(args) {
  let CustomDatabaseAdapter = class CustomDatabaseAdapter extends DatabaseAdapter {
    static {
      __name(this, "CustomDatabaseAdapter");
    }
    fields = args.fields;
    models = args.models;
    query = args.query;
    migrations = args.migrations;
    static new = args.new;
    duplicate = args.duplicate;
    isConnected = args.isConnected;
    close = args.close;
    transaction = args.transaction;
  };
  return CustomDatabaseAdapter;
}
__name(databaseAdapter, "databaseAdapter");
var DatabaseAdapter = class {
  static {
    __name(this, "DatabaseAdapter");
  }
  $$type = "$PDatabaseAdapter";
  connectionName;
  databaseSettings;
  initializedModels = {};
  models;
  fields;
  query;
  migrations;
  ModelType;
  instance;
  __argumentsUsed;
  __ignoreNotImplementedErrors = false;
  __modelsFilteredOutOfEngine;
  __modelsOfEngine;
  __indirectlyRelatedModels = {};
  /**
  * Factory function for creating a new DatabaseAdapter instance. Your engine should always implement this function
  * as static and return a new instance of your engine.
  *
  * @returns - Will return a new engine instance.
  */
  static new(..._args) {
    throw new NotImplementedAdapterException("new");
  }
  /**
  * Duplicates this instance to a new instance so we can work on it instead of the default one. Generally
  * you will not need to worry too much about this, this is used more on migrations so we can keep the state
  * models separated from the original models.
  *
  * @example
  * ```ts
  * async duplicate(getNewEngine: () => Promise<DatabaseAdapter>) {
  *    const duplicatedEngine = await getNewEngine();
  *    await duplicatedEngine.connection.close();
  *    await duplicatedEngine.connection.connect();
  *    return duplicatedEngine;
  * }
  * ```
  *
  * @param _getNewEngine - Default duplicate function, this should be called or it will throw an error.
  *
  * @returns - A new engine instance after calling `.new` static method.
  */
  // eslint-disable-next-line ts/require-await
  async duplicate(_getNewEngine) {
    throw new NotImplementedAdapterException("duplicate");
  }
  /**
  * We use this to see check if we have a connection to the database or not. We will only translate the models if we
  * have a connection to the database. If your orm does not rely on a connection to create the models you can return
  * true by default.
  *
  * @return - Return true if the database is connected or false otherwise.
  */
  // eslint-disable-next-line ts/require-await
  async isConnected(_engine) {
    throw new NotImplementedAdapterException("isConnected");
  }
  /**
  * Called when we want to close all of the connections to the database, if your engine can close the connection
  * automatically this don't need to be used.
  *
  * @example
  * ```ts
  *
  * ```
  */
  // eslint-disable-next-line ts/require-await
  async close(_engine) {
    throw new NotImplementedAdapterException("close");
  }
  /**
  * A transaction is a database transaction, this is used to guarantee that all of the queries we do will run inside
  * of a transaction.
  *
  * @param callback - The callback that will be called to run inside of a transaction.
  * @param args - The arguments of the callback.
  *
  * @return - The return value of the callback.
  */
  async transaction(_databaseAdapter, callback, ...args) {
    const transact = void 0;
    return await Promise.resolve(callback(transact, ...args));
  }
  /**
  * A transaction is kinda strange, but it's a function that will run another function inside of it. With this
  * we can guarantee that a given piece of code will run inside of the transaction. After it finishes it returns
  * the value normally.
  *
  * @example
  * ```
  * function transactionMultiply(transaction: SequelizeTransaction, a: number, b: number) {
  *    return a * b;
  * }
  *
  * const result = await engineInstance.useTransaction(transactionMultiply, 2, 2)
  *
  * result // 4
  * ```
  *
  * On the example above, transactionMultiply run in a transaction and we pass the variables of this function on the
  * other arguments. The first argument is always the callback. The rest are the arguments of the callback function.
  *
  * @param callback - The callback that will be called to run inside of a transaction.
  * @param args - The arguments of the callback.
  *
  * @return - The return value of the callback.
  */
  async useTransaction(callback, ...args) {
    return await this.transaction(this, callback, ...args);
  }
};
export {
  DatabaseAdapter,
  databaseAdapter
};
