{"version":3,"file":"diff.mjs","sources":["../../src/schema/diff.ts"],"sourcesContent":["import _ from 'lodash/fp';\nimport type {\n  Schema,\n  Table,\n  SchemaDiff,\n  Index,\n  ForeignKey,\n  Column,\n  IndexDiff,\n  IndexesDiff,\n  ForeignKeyDiff,\n  ForeignKeysDiff,\n  ColumnDiff,\n  TableDiff,\n  ColumnsDiff,\n} from './types';\nimport type { Database } from '..';\n\ntype PersistedTable = {\n  name: string;\n  dependsOn?: Array<{ name: string }>;\n};\n\ntype TableDiffContext = {\n  previousTable?: Table;\n  databaseTable: Table;\n  userSchemaTable: Table;\n};\n\ntype SchemaDiffContext = {\n  previousSchema?: Schema;\n  databaseSchema: Schema;\n  userSchema: Schema;\n};\n\n// TODO: get that list dynamically instead\nconst RESERVED_TABLE_NAMES = [\n  'strapi_migrations',\n  'strapi_migrations_internal',\n  'strapi_database_schema',\n];\n\nconst statuses = {\n  CHANGED: 'CHANGED',\n  UNCHANGED: 'UNCHANGED',\n} as const;\n\n// NOTE:We could move the schema to use maps of tables & columns instead of arrays to make it easier to diff\n// => this will make the creation a bit more complicated (ordering, Object.values(tables | columns)) -> not a big pbl\n\nconst helpers = {\n  hasTable(schema: Schema, tableName: string) {\n    return schema.tables.findIndex((table) => table.name === tableName) !== -1;\n  },\n  findTable(schema: Schema, tableName: string) {\n    return schema.tables.find((table) => table.name === tableName);\n  },\n  hasColumn(table: Table, columnName: string) {\n    return table.columns.findIndex((column) => column.name === columnName) !== -1;\n  },\n  findColumn(table: Table, columnName: string) {\n    return table.columns.find((column) => column.name === columnName);\n  },\n\n  hasIndex(table: Table, columnName: string) {\n    return table.indexes.findIndex((column) => column.name === columnName) !== -1;\n  },\n  findIndex(table: Table, columnName: string) {\n    return table.indexes.find((column) => column.name === columnName);\n  },\n\n  hasForeignKey(table: Table, columnName: string) {\n    return table.foreignKeys.findIndex((column) => column.name === columnName) !== -1;\n  },\n  findForeignKey(table: Table, columnName: string) {\n    return table.foreignKeys.find((column) => column.name === columnName);\n  },\n};\n\nexport default (db: Database) => {\n  const hasChangedStatus = (diff: { status: 'CHANGED' | 'UNCHANGED' }) =>\n    diff.status === statuses.CHANGED;\n\n  /**\n   * Compares two indexes info\n   * @param {Object} oldIndex - index info read from DB\n   * @param {Object} index - newly generate index info\n   */\n  const diffIndexes = (oldIndex: Index, index: Index): IndexDiff => {\n    const changes: string[] = [];\n\n    // use xor to avoid differences in order\n    if (_.xor(oldIndex.columns, index.columns).length > 0) {\n      changes.push('columns');\n    }\n\n    if (oldIndex.type && index.type && _.toLower(oldIndex.type) !== _.toLower(index.type)) {\n      changes.push('type');\n    }\n\n    return {\n      status: changes.length > 0 ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        name: index.name,\n        object: index,\n      },\n    };\n  };\n\n  /**\n   * Compares two foreign keys info\n   * @param {Object} oldForeignKey - foreignKey info read from DB\n   * @param {Object} foreignKey - newly generate foreignKey info\n   */\n  const diffForeignKeys = (oldForeignKey: ForeignKey, foreignKey: ForeignKey): ForeignKeyDiff => {\n    const changes: string[] = [];\n\n    if (_.difference(oldForeignKey.columns, foreignKey.columns).length > 0) {\n      changes.push('columns');\n    }\n\n    if (_.difference(oldForeignKey.referencedColumns, foreignKey.referencedColumns).length > 0) {\n      changes.push('referencedColumns');\n    }\n\n    if (oldForeignKey.referencedTable !== foreignKey.referencedTable) {\n      changes.push('referencedTable');\n    }\n\n    if (_.isNil(oldForeignKey.onDelete) || _.toUpper(oldForeignKey.onDelete) === 'NO ACTION') {\n      if (\n        !_.isNil(foreignKey.onDelete) &&\n        _.toUpper(oldForeignKey.onDelete ?? '') !== 'NO ACTION'\n      ) {\n        changes.push('onDelete');\n      }\n    } else if (_.toUpper(oldForeignKey.onDelete) !== _.toUpper(foreignKey.onDelete ?? '')) {\n      changes.push('onDelete');\n    }\n\n    if (_.isNil(oldForeignKey.onUpdate) || _.toUpper(oldForeignKey.onUpdate) === 'NO ACTION') {\n      if (\n        !_.isNil(foreignKey.onUpdate) &&\n        _.toUpper(oldForeignKey.onUpdate ?? '') !== 'NO ACTION'\n      ) {\n        changes.push('onUpdate');\n      }\n    } else if (_.toUpper(oldForeignKey.onUpdate) !== _.toUpper(foreignKey.onUpdate ?? '')) {\n      changes.push('onUpdate');\n    }\n\n    return {\n      status: changes.length > 0 ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        name: foreignKey.name,\n        object: foreignKey,\n      },\n    };\n  };\n\n  const diffDefault = (oldColumn: Column, column: Column) => {\n    const oldDefaultTo = oldColumn.defaultTo;\n    const { defaultTo } = column;\n\n    if (oldDefaultTo === null || _.toLower(oldDefaultTo) === 'null') {\n      return _.isNil(defaultTo) || _.toLower(defaultTo) === 'null';\n    }\n\n    return (\n      _.toLower(oldDefaultTo) === _.toLower(column.defaultTo) ||\n      _.toLower(oldDefaultTo) === _.toLower(`'${column.defaultTo}'`)\n    );\n  };\n\n  /**\n   * Compares two columns info\n   * @param {Object} oldColumn - column info read from DB\n   * @param {Object} column - newly generate column info\n   */\n  const diffColumns = (oldColumn: Column, column: Column): ColumnDiff => {\n    const changes: string[] = [];\n\n    const isIgnoredType = ['increments'].includes(column.type);\n    const oldType = oldColumn.type;\n    const type = db.dialect.getSqlType(column.type);\n\n    if (oldType !== type && !isIgnoredType) {\n      changes.push('type');\n    }\n\n    // NOTE: compare args at some point and split them into specific properties instead\n\n    if (oldColumn.notNullable !== column.notNullable) {\n      changes.push('notNullable');\n    }\n\n    const hasSameDefault = diffDefault(oldColumn, column);\n    if (!hasSameDefault) {\n      changes.push('defaultTo');\n    }\n\n    if (oldColumn.unsigned !== column.unsigned && db.dialect.supportsUnsigned()) {\n      changes.push('unsigned');\n    }\n\n    return {\n      status: changes.length > 0 ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        name: column.name,\n        object: column,\n      },\n    };\n  };\n\n  const diffTableColumns = (diffCtx: TableDiffContext): ColumnsDiff => {\n    const { databaseTable, userSchemaTable, previousTable } = diffCtx;\n\n    const addedColumns: Column[] = [];\n    const updatedColumns: ColumnDiff['diff'][] = [];\n    const unchangedColumns: Column[] = [];\n    const removedColumns: Column[] = [];\n\n    for (const userSchemaColumn of userSchemaTable.columns) {\n      const databaseColumn = helpers.findColumn(databaseTable, userSchemaColumn.name);\n\n      if (databaseColumn) {\n        const { status, diff } = diffColumns(databaseColumn, userSchemaColumn);\n\n        if (status === statuses.CHANGED) {\n          updatedColumns.push(diff);\n        } else {\n          unchangedColumns.push(databaseColumn);\n        }\n      } else {\n        addedColumns.push(userSchemaColumn);\n      }\n    }\n\n    for (const databaseColumn of databaseTable.columns) {\n      if (\n        !helpers.hasColumn(userSchemaTable, databaseColumn.name) &&\n        previousTable &&\n        helpers.hasColumn(previousTable, databaseColumn.name)\n      ) {\n        removedColumns.push(databaseColumn);\n      }\n    }\n\n    const hasChanged = [addedColumns, updatedColumns, removedColumns].some((arr) => arr.length > 0);\n\n    return {\n      status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        added: addedColumns,\n        updated: updatedColumns,\n        unchanged: unchangedColumns,\n        removed: removedColumns,\n      },\n    };\n  };\n\n  const diffTableIndexes = (diffCtx: TableDiffContext): IndexesDiff => {\n    const { databaseTable, userSchemaTable, previousTable } = diffCtx;\n\n    const addedIndexes: Index[] = [];\n    const updatedIndexes: IndexDiff['diff'][] = [];\n    const unchangedIndexes: Index[] = [];\n    const removedIndexes: Index[] = [];\n\n    for (const userSchemaIndex of userSchemaTable.indexes) {\n      const databaseIndex = helpers.findIndex(databaseTable, userSchemaIndex.name);\n      if (databaseIndex) {\n        const { status, diff } = diffIndexes(databaseIndex, userSchemaIndex);\n\n        if (status === statuses.CHANGED) {\n          updatedIndexes.push(diff);\n        } else {\n          unchangedIndexes.push(databaseIndex);\n        }\n      } else {\n        addedIndexes.push(userSchemaIndex);\n      }\n    }\n\n    for (const databaseIndex of databaseTable.indexes) {\n      if (\n        !helpers.hasIndex(userSchemaTable, databaseIndex.name) &&\n        previousTable &&\n        helpers.hasIndex(previousTable, databaseIndex.name)\n      ) {\n        removedIndexes.push(databaseIndex);\n      }\n    }\n\n    const hasChanged = [addedIndexes, updatedIndexes, removedIndexes].some((arr) => arr.length > 0);\n\n    return {\n      status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        added: addedIndexes,\n        updated: updatedIndexes,\n        unchanged: unchangedIndexes,\n        removed: removedIndexes,\n      },\n    };\n  };\n\n  const diffTableForeignKeys = (diffCtx: TableDiffContext): ForeignKeysDiff => {\n    const { databaseTable, userSchemaTable, previousTable } = diffCtx;\n\n    const addedForeignKeys: ForeignKey[] = [];\n    const updatedForeignKeys: ForeignKeyDiff['diff'][] = [];\n    const unchangedForeignKeys: ForeignKey[] = [];\n    const removedForeignKeys: ForeignKey[] = [];\n\n    if (!db.dialect.usesForeignKeys()) {\n      return {\n        status: statuses.UNCHANGED,\n        diff: {\n          added: addedForeignKeys,\n          updated: updatedForeignKeys,\n          unchanged: unchangedForeignKeys,\n          removed: removedForeignKeys,\n        },\n      };\n    }\n\n    for (const userSchemaForeignKeys of userSchemaTable.foreignKeys) {\n      const databaseForeignKeys = helpers.findForeignKey(databaseTable, userSchemaForeignKeys.name);\n      if (databaseForeignKeys) {\n        const { status, diff } = diffForeignKeys(databaseForeignKeys, userSchemaForeignKeys);\n\n        if (status === statuses.CHANGED) {\n          updatedForeignKeys.push(diff);\n        } else {\n          unchangedForeignKeys.push(databaseForeignKeys);\n        }\n      } else {\n        addedForeignKeys.push(userSchemaForeignKeys);\n      }\n    }\n\n    for (const databaseForeignKeys of databaseTable.foreignKeys) {\n      if (\n        !helpers.hasForeignKey(userSchemaTable, databaseForeignKeys.name) &&\n        previousTable &&\n        helpers.hasForeignKey(previousTable, databaseForeignKeys.name)\n      ) {\n        removedForeignKeys.push(databaseForeignKeys);\n      }\n    }\n\n    const hasChanged = [addedForeignKeys, updatedForeignKeys, removedForeignKeys].some(\n      (arr) => arr.length > 0\n    );\n\n    return {\n      status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        added: addedForeignKeys,\n        updated: updatedForeignKeys,\n        unchanged: unchangedForeignKeys,\n        removed: removedForeignKeys,\n      },\n    };\n  };\n\n  const diffTables = (diffCtx: TableDiffContext): TableDiff => {\n    const { databaseTable } = diffCtx;\n\n    const columnsDiff = diffTableColumns(diffCtx);\n    const indexesDiff = diffTableIndexes(diffCtx);\n    const foreignKeysDiff = diffTableForeignKeys(diffCtx);\n\n    const hasChanged = [columnsDiff, indexesDiff, foreignKeysDiff].some(hasChangedStatus);\n\n    return {\n      status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        name: databaseTable.name,\n        indexes: indexesDiff.diff,\n        foreignKeys: foreignKeysDiff.diff,\n        columns: columnsDiff.diff,\n      },\n    };\n  };\n\n  const diffSchemas = async (schemaDiffCtx: SchemaDiffContext): Promise<SchemaDiff> => {\n    const { previousSchema, databaseSchema, userSchema } = schemaDiffCtx;\n\n    const addedTables: Table[] = [];\n    const updatedTables: TableDiff['diff'][] = [];\n    const unchangedTables: Table[] = [];\n    const removedTables: Table[] = [];\n\n    // for each table in the user schema, check if it already exists in the database schema\n    for (const userSchemaTable of userSchema.tables) {\n      const databaseTable = helpers.findTable(databaseSchema, userSchemaTable.name);\n      const previousTable =\n        previousSchema && helpers.findTable(previousSchema, userSchemaTable.name);\n\n      if (databaseTable) {\n        const { status, diff } = diffTables({\n          previousTable,\n          databaseTable,\n          userSchemaTable,\n        });\n\n        if (status === statuses.CHANGED) {\n          updatedTables.push(diff);\n        } else {\n          unchangedTables.push(databaseTable);\n        }\n      } else {\n        addedTables.push(userSchemaTable);\n      }\n    }\n\n    // maintain audit logs table from EE -> CE\n    const parsePersistedTable = (persistedTable: string | Table) => {\n      if (typeof persistedTable === 'string') {\n        return persistedTable;\n      }\n      return persistedTable.name;\n    };\n\n    const persistedTables = helpers.hasTable(databaseSchema, 'strapi_core_store_settings')\n      ? // TODO: replace with low level db query instead\n        ((await strapi.store.get({\n          type: 'core',\n          key: 'persisted_tables',\n        })) ?? [])\n      : [];\n\n    const reservedTables = [...RESERVED_TABLE_NAMES, ...persistedTables.map(parsePersistedTable)];\n\n    // for all tables in the database schema, check if they are not in the user schema\n    for (const databaseTable of databaseSchema.tables) {\n      const isInUserSchema = helpers.hasTable(userSchema, databaseTable.name);\n      const wasTracked = previousSchema && helpers.hasTable(previousSchema, databaseTable.name);\n      const isReserved = reservedTables.includes(databaseTable.name);\n\n      // NOTE: if db table is not in the user schema and is not in the previous stored schema leave it alone. it is a user custom table that we should not touch\n      if (!isInUserSchema && !wasTracked) {\n        continue;\n      }\n\n      // if a db table is not in the user schema I want to delete it\n      if (!isInUserSchema && wasTracked && !isReserved) {\n        const dependencies = persistedTables\n          .filter((table: PersistedTable) => {\n            const dependsOn = table?.dependsOn;\n\n            if (!_.isArray(dependsOn)) {\n              return;\n            }\n\n            return dependsOn.some((table) => table.name === databaseTable.name);\n          })\n          .map((dependsOnTable: PersistedTable) => {\n            return databaseSchema.tables.find(\n              (databaseTable) => databaseTable.name === dependsOnTable.name\n            );\n          })\n          // In case the table is not found, filter undefined values\n          .filter((table: PersistedTable) => !_.isNil(table));\n\n        removedTables.push(databaseTable, ...dependencies);\n      }\n    }\n\n    const hasChanged = [addedTables, updatedTables, removedTables].some((arr) => arr.length > 0);\n\n    return {\n      status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,\n      diff: {\n        tables: {\n          added: addedTables,\n          updated: updatedTables,\n          unchanged: unchangedTables,\n          removed: removedTables,\n        },\n      },\n    };\n  };\n\n  return {\n    diff: diffSchemas,\n  };\n};\n"],"names":["RESERVED_TABLE_NAMES","statuses","CHANGED","UNCHANGED","helpers","hasTable","schema","tableName","tables","findIndex","table","name","findTable","find","hasColumn","columnName","columns","column","findColumn","hasIndex","indexes","hasForeignKey","foreignKeys","findForeignKey","db","hasChangedStatus","diff","status","diffIndexes","oldIndex","index","changes","_","xor","length","push","type","toLower","object","diffForeignKeys","oldForeignKey","foreignKey","difference","referencedColumns","referencedTable","isNil","onDelete","toUpper","onUpdate","diffDefault","oldColumn","oldDefaultTo","defaultTo","diffColumns","isIgnoredType","includes","oldType","dialect","getSqlType","notNullable","hasSameDefault","unsigned","supportsUnsigned","diffTableColumns","diffCtx","databaseTable","userSchemaTable","previousTable","addedColumns","updatedColumns","unchangedColumns","removedColumns","userSchemaColumn","databaseColumn","hasChanged","some","arr","added","updated","unchanged","removed","diffTableIndexes","addedIndexes","updatedIndexes","unchangedIndexes","removedIndexes","userSchemaIndex","databaseIndex","diffTableForeignKeys","addedForeignKeys","updatedForeignKeys","unchangedForeignKeys","removedForeignKeys","usesForeignKeys","userSchemaForeignKeys","databaseForeignKeys","diffTables","columnsDiff","indexesDiff","foreignKeysDiff","diffSchemas","schemaDiffCtx","previousSchema","databaseSchema","userSchema","addedTables","updatedTables","unchangedTables","removedTables","parsePersistedTable","persistedTable","persistedTables","strapi","store","get","key","reservedTables","map","isInUserSchema","wasTracked","isReserved","dependencies","filter","dependsOn","isArray","dependsOnTable"],"mappings":"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"}