"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/migrations/actions/fields.ts
var fields_exports = {};
__export(fields_exports, {
  ChangeField: () => ChangeField,
  CreateField: () => CreateField,
  DeleteField: () => DeleteField,
  RenameField: () => RenameField
});
module.exports = __toCommonJS(fields_exports);

// src/migrations/actions/operation.ts
var Operation = class {
  static {
    __name(this, "Operation");
  }
  /**
  * Function that will be used to construct and build the state of all of the models in the application so we
  * can compare to the original ones.
  *
  * @param state - A state instance that holds all of the models of the application before.
  * @param domainName - The name of the domain where this model was defined.
  * @param domainPath - The path of the domain where this model exists so we can add the migration file there.
  */
  async stateForwards(_state, _domainName, _domainPath) {
  }
  /**
  * Method that runs when a migration is running on a migration file, when this happens we will call the exact
  * function of the engine migrations.
  *
  * We also have the fromState (which will be state when the state) which will be the state of the models
  * before running the migration and `toState` will be state AFTER running the migration
  */
  async run(_migration, _engineInstance, _fromState, _toState, _returnOfInit) {
  }
  // eslint-disable-next-line ts/require-await
  static async defaultToGenerate(domainName, domainPath, modelName, data) {
    return {
      operation: this,
      domainName,
      domainPath,
      modelName,
      order: 0,
      dependsOn: [],
      data
    };
  }
  // eslint-disable-next-line ts/require-await
  static async toString(_engine, indentation = 0, data) {
    return {
      asString: ""
    };
  }
  // eslint-disable-next-line ts/require-await
  static async defaultToString(indentation = 0, customAttributesOfAction = "") {
    const ident = "  ".repeat(indentation);
    return `${ident}new actions.${this.name}(${customAttributesOfAction !== "" ? `
${customAttributesOfAction}
${ident}` : ""})`;
  }
  // eslint-disable-next-line ts/require-await
  static async describe(data) {
    return "";
  }
};

// src/migrations/actions/fields.ts
var CreateField = class extends Operation {
  static {
    __name(this, "CreateField");
  }
  modelName;
  fieldName;
  fieldDefinition;
  constructor(modelName, fieldName, fieldDefinition) {
    super();
    this.modelName = modelName;
    this.fieldName = fieldName;
    this.fieldDefinition = fieldDefinition;
  }
  async stateForwards(state, domainName, domainPath) {
    const model = await state.get(this.modelName);
    const modelConstructor = model.constructor;
    modelConstructor["__domainName"] = domainName;
    modelConstructor["__domainPath"] = domainPath;
    model.fields[this.fieldName] = this.fieldDefinition;
    await state.set(this.modelName, model);
  }
  async run(migration, engineInstance, fromState, toState, returnOfInit) {
    const toModel = toState[this.modelName];
    const fromModel = fromState[this.modelName];
    await engineInstance.migrations?.addField(engineInstance, toModel, fromModel, this.fieldName, migration, returnOfInit);
  }
  static async toGenerate(domainName, domainPath, modelName, data) {
    return super.defaultToGenerate(domainName, domainPath, modelName, data);
  }
  static async toString(engine, indentation = 0, data) {
    const ident = "  ".repeat(indentation);
    return {
      asString: await super.defaultToString(indentation - 1, `${ident}"${data.modelName}",
${ident}"${data.data.fieldName}",
${await data.data.fieldDefinition["__toString"](engine)}`),
      customImports: await data.data.fieldDefinition["__getCustomImports"]()
    };
  }
  // eslint-disable-next-line ts/require-await
  static async describe(data) {
    return `Created the field '${data.data.fieldName}' on the '${data.modelName}' model`;
  }
};
var ChangeField = class extends Operation {
  static {
    __name(this, "ChangeField");
  }
  modelName;
  fieldName;
  fieldDefinitionBefore;
  fieldDefinitionAfter;
  constructor(modelName, fieldName, fieldDefinitionBefore, fieldDefinitionAfter) {
    super();
    this.modelName = modelName;
    this.fieldName = fieldName;
    this.fieldDefinitionBefore = fieldDefinitionBefore;
    this.fieldDefinitionAfter = fieldDefinitionAfter;
  }
  async stateForwards(state, domainName, domainPath) {
    const model = await state.get(this.modelName);
    const modelConstructor = model.constructor;
    modelConstructor["__domainName"] = domainName;
    modelConstructor["__domainPath"] = domainPath;
    model.fields[this.fieldName] = this.fieldDefinitionAfter;
    await state.set(this.modelName, model);
  }
  async run(migration, engineInstance, fromState, toState, returnOfInit) {
    const fromModel = fromState[this.modelName];
    const toModel = toState[this.modelName];
    await engineInstance.migrations?.changeField(engineInstance, toModel, fromModel, this.fieldDefinitionBefore, this.fieldDefinitionAfter, migration, returnOfInit);
  }
  static async toGenerate(domainName, domainPath, modelName, data) {
    return super.defaultToGenerate(domainName, domainPath, modelName, data);
  }
  static async toString(engine, indentation = 0, data) {
    const ident = "  ".repeat(indentation);
    return {
      asString: await super.defaultToString(indentation - 1, `${ident}"${data.modelName}",
${ident}"${data.data.fieldName}",
${await data.data.fieldDefinitionBefore["__toString"](engine)},
${await data.data.fieldDefinitionAfter["__toString"](engine)}`),
      customImports: (await data.data.fieldDefinitionBefore["__getCustomImports"]()).concat(await data.data.fieldDefinitionAfter["__getCustomImports"]())
    };
  }
  // eslint-disable-next-line ts/require-await
  static async describe(data) {
    return `Changed the ${`attribute${data.data.changedAttributes.length > 1 ? "s" : ""} ${data.data.changedAttributes.map((attribute) => `'${attribute}'`).join(", ").replace(/,(?!.*,)/, " and")}`} of the '${data.data.fieldName}' field on the '${data.modelName}' model`;
  }
};
var RenameField = class extends Operation {
  static {
    __name(this, "RenameField");
  }
  modelName;
  fieldNameBefore;
  fieldNameAfter;
  fieldDefinition;
  constructor(modelName, fieldNameBefore, fieldNameAfter, fieldDefinition) {
    super();
    this.modelName = modelName;
    this.fieldNameBefore = fieldNameBefore;
    this.fieldNameAfter = fieldNameAfter;
    this.fieldDefinition = fieldDefinition;
  }
  async stateForwards(state, domainName, domainPath) {
    const model = await state.get(this.modelName);
    const modelConstructor = model.constructor;
    modelConstructor["__domainName"] = domainName;
    modelConstructor["__domainPath"] = domainPath;
    const hasNamesReallyChanged = this.fieldNameAfter !== this.fieldNameBefore;
    if (hasNamesReallyChanged) {
      model.fields[this.fieldNameAfter] = model.fields[this.fieldNameBefore];
      delete model.fields[this.fieldNameBefore];
    }
    model.fields[this.fieldNameAfter] = this.fieldDefinition;
    await state.set(this.modelName, model);
  }
  async run(migration, engineInstance, fromState, toState, returnOfInit) {
    const fromModel = fromState[this.modelName];
    const toModel = toState[this.modelName];
    await engineInstance.migrations?.renameField(engineInstance, toModel, fromModel, this.fieldNameBefore, this.fieldNameAfter, migration, returnOfInit);
  }
  static async toGenerate(domainName, domainPath, modelName, data) {
    return super.defaultToGenerate(domainName, domainPath, modelName, data);
  }
  static async toString(engine, indentation = 0, data) {
    const ident = "  ".repeat(indentation);
    return {
      asString: await super.defaultToString(indentation - 1, `${ident}"${data.modelName}",
${ident}"${data.data.fieldNameBefore}",
${ident}"${data.data.fieldNameAfter}",
${await data.data.fieldDefinition["__toString"](engine)}`),
      customImports: await data.data.fieldDefinition["__getCustomImports"]()
    };
  }
  // eslint-disable-next-line ts/require-await
  static async describe(data) {
    return `Renamed the field '${data.data.fieldNameBefore}' to '${data.data.fieldNameAfter}' on the '${data.modelName}' model`;
  }
};
var DeleteField = class extends Operation {
  static {
    __name(this, "DeleteField");
  }
  modelName;
  fieldName;
  constructor(modelName, fieldName) {
    super();
    this.modelName = modelName;
    this.fieldName = fieldName;
  }
  async stateForwards(state, domainName, domainPath) {
    const model = await state.get(this.modelName);
    const modelConstructor = model.constructor;
    modelConstructor["__domainName"] = domainName;
    modelConstructor["__domainPath"] = domainPath;
    delete model.fields[this.fieldName];
    await state.set(this.modelName, model);
  }
  async run(migration, engineInstance, fromState, toState, returnOfInit) {
    const fromModel = fromState[this.modelName];
    const toModel = toState[this.modelName];
    await engineInstance.migrations?.removeField(engineInstance, toModel, fromModel, this.fieldName, migration, returnOfInit);
  }
  static async toGenerate(domainName, domainPath, modelName, data) {
    return super.defaultToGenerate(domainName, domainPath, modelName, data);
  }
  static async toString(_engine, indentation = 0, data) {
    const ident = "  ".repeat(indentation);
    return {
      asString: await super.defaultToString(indentation - 1, `${ident}"${data.modelName}",
${ident}"${data.data.fieldName}"`)
    };
  }
  // eslint-disable-next-line ts/require-await
  static async describe(data) {
    return `Removed the field '${data.data.fieldName}' on the '${data.modelName}' model`;
  }
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ChangeField,
  CreateField,
  DeleteField,
  RenameField
});
