{"version":3,"file":"5.0.0-01-convert-identifiers-long-than-max-length.mjs","sources":["../../../src/migrations/internal-migrations/5.0.0-01-convert-identifiers-long-than-max-length.ts"],"sourcesContent":["import type { Knex } from 'knex';\nimport createDebug from 'debug';\nimport type { Migration } from '../common';\nimport type { Metadata } from '../../metadata';\nimport { type Database } from '../..';\nimport { identifiers } from '../../utils/identifiers';\n\nconst debug = createDebug('strapi::database::migration');\n\ntype NameDiff<T> = {\n  short: T;\n  full: T;\n};\n\ntype IndexDiff = NameDiff<{ index: number; key: string; tableName: string; indexName: string }>;\n\n// key isn't really used except for debugging, but it's helpful to track down problems\ntype IdentifierDiffs = {\n  indexes: IndexDiff[];\n  tables: NameDiff<{ index: number; key: string; tableName: string }>[];\n  columns: NameDiff<{ index: number; key: string; tableName: string; columnName: string }>[];\n};\n\nexport const renameIdentifiersLongerThanMaxLength: Migration = {\n  name: '5.0.0-rename-identifiers-longer-than-max-length',\n  async up(knex, db) {\n    const md = db.metadata;\n\n    const diffs = findDiffs(md);\n    // migrate indexes before tables so we know to target the original tableName\n    for (const indexDiff of diffs.indexes) {\n      await renameIndex(knex, db, indexDiff);\n    }\n\n    // migrate columns before table names so we know to target the original tableName\n    for (const columnDiff of diffs.columns) {\n      const { full, short } = columnDiff;\n      const tableName = full.tableName;\n\n      const hasTable = await knex.schema.hasTable(tableName);\n\n      if (hasTable) {\n        // tablebuilder methods MUST be synchronous and so you cannot use async inside it, which is why we check the column here\n        const hasColumn = await knex.schema.hasColumn(tableName, full.columnName);\n\n        if (hasColumn) {\n          await knex.schema.alterTable(tableName, async (table) => {\n            debug(`renaming column ${full.columnName} to ${short.columnName}`);\n            table.renameColumn(full.columnName, short.columnName);\n          });\n        }\n      }\n    }\n\n    // migrate table names\n    for (const tableDiff of diffs.tables) {\n      const hasTable = await knex.schema.hasTable(tableDiff.full.tableName);\n\n      if (hasTable) {\n        debug(`renaming table ${tableDiff.full.tableName} to ${tableDiff.short.tableName}`);\n        await knex.schema.renameTable(tableDiff.full.tableName, tableDiff.short.tableName);\n      }\n    }\n  },\n  async down() {\n    throw new Error('not implemented');\n  },\n};\n\nconst renameIndex = async (knex: Knex, db: Database, diff: IndexDiff) => {\n  const client = db.config.connection.client;\n  const short = diff.short;\n  const full = diff.full;\n\n  if (full.indexName === short.indexName) {\n    debug(`not renaming index ${full.indexName} because name hasn't changed`);\n    return;\n  }\n\n  // fk indexes can't be easily renamed, and will be recreated by db sync\n  // if this misses something due to the loose string matching, it's not critical, it just means index will be rebuilt in db sync\n  if (short.indexName.endsWith('fk') || full.indexName.endsWith('fk')) {\n    return;\n  }\n\n  debug(`renaming index from ${full.indexName} to ${short.indexName}`);\n\n  // If schema creation has never actually run before, none of these will exist, and they will throw an error\n  // we have no way of running an \"if exists\" other than a per-dialect manual check, which we won't do\n  // because even if it fails for some other reason, the schema sync will recreate them anyway\n  // Therefore, we wrap this in a nested transaction (considering we are running this migration in a transaction)\n  // so that we can suppress the error\n  try {\n    await knex.transaction(async (trx) => {\n      if (client === 'mysql' || client === 'mariadb') {\n        await knex\n          .raw('ALTER TABLE ?? RENAME INDEX ?? TO ??', [\n            full.tableName,\n            full.indexName,\n            short.indexName,\n          ])\n          .transacting(trx);\n      } else if (client === 'pg' || client === 'postgres') {\n        await knex\n          .raw('ALTER INDEX ?? RENAME TO ??', [full.indexName, short.indexName])\n          .transacting(trx);\n      } else if (['sqlite', 'sqlite3', 'better-sqlite3'].includes(client as any)) {\n        // SQLite doesn't support renaming, so rather than trying to drop/recreate we'll let db sync handle it\n        debug(`SQLite does not support index renaming, not renaming index ${full.indexName}`);\n      } else {\n        debug(`No db client name matches, not renaming index ${full.indexName}`);\n      }\n    });\n  } catch (err) {\n    debug(`error creating index: ${JSON.stringify(err)}`);\n  }\n};\n\nconst findDiffs = (shortMap: Metadata) => {\n  const diffs = {\n    tables: [],\n    columns: [],\n    indexes: [],\n  } as IdentifierDiffs;\n\n  const shortArr = Array.from(shortMap.entries());\n\n  shortArr.forEach(([, shortObj], index) => {\n    const fullTableName = identifiers.getUnshortenedName(shortObj.tableName);\n    if (!fullTableName) {\n      throw new Error(`Missing full table name for ${shortObj.tableName}`);\n    }\n\n    // find table name diffs\n    if (shortObj.tableName !== fullTableName) {\n      diffs.tables.push({\n        full: {\n          index,\n          key: 'tableName',\n          tableName: fullTableName,\n        },\n        short: {\n          index,\n          key: 'tableName',\n          tableName: shortObj.tableName,\n        },\n      });\n    }\n\n    // find column name diffs\n    // eslint-disable-next-line guard-for-in\n    for (const attrKey in shortObj.attributes) {\n      if (shortObj.attributes[attrKey].type === 'relation') {\n        continue;\n      }\n\n      // TODO: add more type checks so we don't need any\n      const attr = shortObj.attributes[attrKey] as any;\n      const shortColumnName = attr.columnName;\n      const longColumnName = identifiers.getUnshortenedName(shortColumnName);\n\n      if (!shortColumnName || !longColumnName) {\n        throw new Error(`missing column name(s) for attribute ${JSON.stringify(attr, null, 2)}`);\n      }\n      if (shortColumnName && longColumnName && shortColumnName !== longColumnName) {\n        diffs.columns.push({\n          short: {\n            index,\n            tableName: fullTableName, // NOTE: this means that we must rename columns before tables\n            key: `attributes.${attrKey}`,\n            columnName: shortColumnName,\n          },\n          full: {\n            index,\n            tableName: fullTableName,\n            key: `attributes.${attrKey}`,\n            columnName: longColumnName,\n          },\n        });\n      }\n    }\n\n    // find index name diffs\n    // eslint-disable-next-line guard-for-in\n    for (const attrKey in shortObj.indexes) {\n      const shortIndexName = shortObj.indexes[attrKey].name;\n      const longIndexName = identifiers.getUnshortenedName(shortIndexName);\n      if (!longIndexName) {\n        throw new Error(`Missing full index name for ${shortIndexName}`);\n      }\n\n      if (shortIndexName && longIndexName && shortIndexName !== longIndexName) {\n        diffs.indexes.push({\n          short: {\n            index,\n            tableName: fullTableName, // NOTE: this means that we must rename columns before tables\n            key: `indexes.${attrKey}`,\n            indexName: shortIndexName,\n          },\n          full: {\n            index,\n            tableName: fullTableName,\n            key: `indexes.${attrKey}`,\n            indexName: longIndexName,\n          },\n        });\n      }\n    }\n  });\n\n  return diffs;\n};\n"],"names":["debug","createDebug","renameIdentifiersLongerThanMaxLength","name","up","knex","db","md","metadata","diffs","findDiffs","indexDiff","indexes","renameIndex","columnDiff","columns","full","short","tableName","hasTable","schema","hasColumn","columnName","alterTable","table","renameColumn","tableDiff","tables","renameTable","down","Error","diff","client","config","connection","indexName","endsWith","transaction","trx","raw","transacting","includes","err","JSON","stringify","shortMap","shortArr","Array","from","entries","forEach","shortObj","index","fullTableName","identifiers","getUnshortenedName","push","key","attrKey","attributes","type","attr","shortColumnName","longColumnName","shortIndexName","longIndexName"],"mappings":";;;AAOA,MAAMA,QAAQC,WAAY,CAAA,6BAAA,CAAA;MAgBbC,oCAAkD,GAAA;IAC7DC,IAAM,EAAA,iDAAA;IACN,MAAMC,EAAAA,CAAAA,CAAGC,IAAI,EAAEC,EAAE,EAAA;QACf,MAAMC,EAAAA,GAAKD,GAAGE,QAAQ;AAEtB,QAAA,MAAMC,QAAQC,SAAUH,CAAAA,EAAAA,CAAAA;;AAExB,QAAA,KAAK,MAAMI,SAAAA,IAAaF,KAAMG,CAAAA,OAAO,CAAE;YACrC,MAAMC,WAAAA,CAAYR,MAAMC,EAAIK,EAAAA,SAAAA,CAAAA;AAC9B;;AAGA,QAAA,KAAK,MAAMG,UAAAA,IAAcL,KAAMM,CAAAA,OAAO,CAAE;AACtC,YAAA,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAGH,UAAAA;YACxB,MAAMI,SAAAA,GAAYF,KAAKE,SAAS;AAEhC,YAAA,MAAMC,WAAW,MAAMd,IAAAA,CAAKe,MAAM,CAACD,QAAQ,CAACD,SAAAA,CAAAA;AAE5C,YAAA,IAAIC,QAAU,EAAA;;gBAEZ,MAAME,SAAAA,GAAY,MAAMhB,IAAKe,CAAAA,MAAM,CAACC,SAAS,CAACH,SAAWF,EAAAA,IAAAA,CAAKM,UAAU,CAAA;AAExE,gBAAA,IAAID,SAAW,EAAA;AACb,oBAAA,MAAMhB,KAAKe,MAAM,CAACG,UAAU,CAACL,WAAW,OAAOM,KAAAA,GAAAA;wBAC7CxB,KAAM,CAAA,CAAC,gBAAgB,EAAEgB,IAAKM,CAAAA,UAAU,CAAC,IAAI,EAAEL,KAAMK,CAAAA,UAAU,CAAE,CAAA,CAAA;AACjEE,wBAAAA,KAAAA,CAAMC,YAAY,CAACT,IAAAA,CAAKM,UAAU,EAAEL,MAAMK,UAAU,CAAA;AACtD,qBAAA,CAAA;AACF;AACF;AACF;;AAGA,QAAA,KAAK,MAAMI,SAAAA,IAAajB,KAAMkB,CAAAA,MAAM,CAAE;YACpC,MAAMR,QAAAA,GAAW,MAAMd,IAAAA,CAAKe,MAAM,CAACD,QAAQ,CAACO,SAAAA,CAAUV,IAAI,CAACE,SAAS,CAAA;AAEpE,YAAA,IAAIC,QAAU,EAAA;AACZnB,gBAAAA,KAAAA,CAAM,CAAC,eAAe,EAAE0B,SAAAA,CAAUV,IAAI,CAACE,SAAS,CAAC,IAAI,EAAEQ,SAAAA,CAAUT,KAAK,CAACC,SAAS,CAAE,CAAA,CAAA;AAClF,gBAAA,MAAMb,IAAKe,CAAAA,MAAM,CAACQ,WAAW,CAACF,SAAAA,CAAUV,IAAI,CAACE,SAAS,EAAEQ,SAAUT,CAAAA,KAAK,CAACC,SAAS,CAAA;AACnF;AACF;AACF,KAAA;IACA,MAAMW,IAAAA,CAAAA,GAAAA;AACJ,QAAA,MAAM,IAAIC,KAAM,CAAA,iBAAA,CAAA;AAClB;AACF;AAEA,MAAMjB,WAAAA,GAAc,OAAOR,IAAAA,EAAYC,EAAcyB,EAAAA,IAAAA,GAAAA;AACnD,IAAA,MAAMC,SAAS1B,EAAG2B,CAAAA,MAAM,CAACC,UAAU,CAACF,MAAM;IAC1C,MAAMf,KAAAA,GAAQc,KAAKd,KAAK;IACxB,MAAMD,IAAAA,GAAOe,KAAKf,IAAI;AAEtB,IAAA,IAAIA,IAAKmB,CAAAA,SAAS,KAAKlB,KAAAA,CAAMkB,SAAS,EAAE;AACtCnC,QAAAA,KAAAA,CAAM,CAAC,mBAAmB,EAAEgB,KAAKmB,SAAS,CAAC,4BAA4B,CAAC,CAAA;AACxE,QAAA;AACF;;;IAIA,IAAIlB,KAAAA,CAAMkB,SAAS,CAACC,QAAQ,CAAC,IAASpB,CAAAA,IAAAA,IAAAA,CAAKmB,SAAS,CAACC,QAAQ,CAAC,IAAO,CAAA,EAAA;AACnE,QAAA;AACF;IAEApC,KAAM,CAAA,CAAC,oBAAoB,EAAEgB,IAAKmB,CAAAA,SAAS,CAAC,IAAI,EAAElB,KAAMkB,CAAAA,SAAS,CAAE,CAAA,CAAA;;;;;;IAOnE,IAAI;QACF,MAAM9B,IAAAA,CAAKgC,WAAW,CAAC,OAAOC,GAAAA,GAAAA;YAC5B,IAAIN,MAAAA,KAAW,OAAWA,IAAAA,MAAAA,KAAW,SAAW,EAAA;gBAC9C,MAAM3B,IAAAA,CACHkC,GAAG,CAAC,sCAAwC,EAAA;AAC3CvB,oBAAAA,IAAAA,CAAKE,SAAS;AACdF,oBAAAA,IAAAA,CAAKmB,SAAS;AACdlB,oBAAAA,KAAAA,CAAMkB;AACP,iBAAA,CAAA,CACAK,WAAW,CAACF,GAAAA,CAAAA;AACjB,aAAA,MAAO,IAAIN,MAAAA,KAAW,IAAQA,IAAAA,MAAAA,KAAW,UAAY,EAAA;gBACnD,MAAM3B,IAAAA,CACHkC,GAAG,CAAC,6BAA+B,EAAA;AAACvB,oBAAAA,IAAAA,CAAKmB,SAAS;AAAElB,oBAAAA,KAAAA,CAAMkB;AAAU,iBAAA,CAAA,CACpEK,WAAW,CAACF,GAAAA,CAAAA;AACjB,aAAA,MAAO,IAAI;AAAC,gBAAA,QAAA;AAAU,gBAAA,SAAA;AAAW,gBAAA;aAAiB,CAACG,QAAQ,CAACT,MAAgB,CAAA,EAAA;;AAE1EhC,gBAAAA,KAAAA,CAAM,CAAC,2DAA2D,EAAEgB,IAAAA,CAAKmB,SAAS,CAAE,CAAA,CAAA;aAC/E,MAAA;AACLnC,gBAAAA,KAAAA,CAAM,CAAC,8CAA8C,EAAEgB,IAAAA,CAAKmB,SAAS,CAAE,CAAA,CAAA;AACzE;AACF,SAAA,CAAA;AACF,KAAA,CAAE,OAAOO,GAAK,EAAA;AACZ1C,QAAAA,KAAAA,CAAM,CAAC,sBAAsB,EAAE2C,IAAKC,CAAAA,SAAS,CAACF,GAAM,CAAA,CAAA,CAAA,CAAA;AACtD;AACF,CAAA;AAEA,MAAMhC,YAAY,CAACmC,QAAAA,GAAAA;AACjB,IAAA,MAAMpC,KAAQ,GAAA;AACZkB,QAAAA,MAAAA,EAAQ,EAAE;AACVZ,QAAAA,OAAAA,EAAS,EAAE;AACXH,QAAAA,OAAAA,EAAS;AACX,KAAA;AAEA,IAAA,MAAMkC,QAAWC,GAAAA,KAAAA,CAAMC,IAAI,CAACH,SAASI,OAAO,EAAA,CAAA;AAE5CH,IAAAA,QAAAA,CAASI,OAAO,CAAC,CAAC,GAAGC,SAAS,EAAEC,KAAAA,GAAAA;AAC9B,QAAA,MAAMC,aAAgBC,GAAAA,WAAAA,CAAYC,kBAAkB,CAACJ,SAASjC,SAAS,CAAA;AACvE,QAAA,IAAI,CAACmC,aAAe,EAAA;AAClB,YAAA,MAAM,IAAIvB,KAAM,CAAA,CAAC,4BAA4B,EAAEqB,QAAAA,CAASjC,SAAS,CAAE,CAAA,CAAA;AACrE;;QAGA,IAAIiC,QAAAA,CAASjC,SAAS,KAAKmC,aAAe,EAAA;YACxC5C,KAAMkB,CAAAA,MAAM,CAAC6B,IAAI,CAAC;gBAChBxC,IAAM,EAAA;AACJoC,oBAAAA,KAAAA;oBACAK,GAAK,EAAA,WAAA;oBACLvC,SAAWmC,EAAAA;AACb,iBAAA;gBACApC,KAAO,EAAA;AACLmC,oBAAAA,KAAAA;oBACAK,GAAK,EAAA,WAAA;AACLvC,oBAAAA,SAAAA,EAAWiC,SAASjC;AACtB;AACF,aAAA,CAAA;AACF;;;AAIA,QAAA,IAAK,MAAMwC,OAAAA,IAAWP,QAASQ,CAAAA,UAAU,CAAE;AACzC,YAAA,IAAIR,SAASQ,UAAU,CAACD,QAAQ,CAACE,IAAI,KAAK,UAAY,EAAA;AACpD,gBAAA;AACF;;AAGA,YAAA,MAAMC,IAAOV,GAAAA,QAAAA,CAASQ,UAAU,CAACD,OAAQ,CAAA;YACzC,MAAMI,eAAAA,GAAkBD,KAAKvC,UAAU;YACvC,MAAMyC,cAAAA,GAAiBT,WAAYC,CAAAA,kBAAkB,CAACO,eAAAA,CAAAA;YAEtD,IAAI,CAACA,eAAmB,IAAA,CAACC,cAAgB,EAAA;gBACvC,MAAM,IAAIjC,KAAM,CAAA,CAAC,qCAAqC,EAAEa,KAAKC,SAAS,CAACiB,IAAM,EAAA,IAAA,EAAM,CAAI,CAAA,CAAA,CAAA,CAAA;AACzF;YACA,IAAIC,eAAAA,IAAmBC,cAAkBD,IAAAA,eAAAA,KAAoBC,cAAgB,EAAA;gBAC3EtD,KAAMM,CAAAA,OAAO,CAACyC,IAAI,CAAC;oBACjBvC,KAAO,EAAA;AACLmC,wBAAAA,KAAAA;wBACAlC,SAAWmC,EAAAA,aAAAA;wBACXI,GAAK,EAAA,CAAC,WAAW,EAAEC,OAAS,CAAA,CAAA;wBAC5BpC,UAAYwC,EAAAA;AACd,qBAAA;oBACA9C,IAAM,EAAA;AACJoC,wBAAAA,KAAAA;wBACAlC,SAAWmC,EAAAA,aAAAA;wBACXI,GAAK,EAAA,CAAC,WAAW,EAAEC,OAAS,CAAA,CAAA;wBAC5BpC,UAAYyC,EAAAA;AACd;AACF,iBAAA,CAAA;AACF;AACF;;;AAIA,QAAA,IAAK,MAAML,OAAAA,IAAWP,QAASvC,CAAAA,OAAO,CAAE;AACtC,YAAA,MAAMoD,iBAAiBb,QAASvC,CAAAA,OAAO,CAAC8C,OAAAA,CAAQ,CAACvD,IAAI;YACrD,MAAM8D,aAAAA,GAAgBX,WAAYC,CAAAA,kBAAkB,CAACS,cAAAA,CAAAA;AACrD,YAAA,IAAI,CAACC,aAAe,EAAA;AAClB,gBAAA,MAAM,IAAInC,KAAAA,CAAM,CAAC,4BAA4B,EAAEkC,cAAgB,CAAA,CAAA,CAAA;AACjE;YAEA,IAAIA,cAAAA,IAAkBC,aAAiBD,IAAAA,cAAAA,KAAmBC,aAAe,EAAA;gBACvExD,KAAMG,CAAAA,OAAO,CAAC4C,IAAI,CAAC;oBACjBvC,KAAO,EAAA;AACLmC,wBAAAA,KAAAA;wBACAlC,SAAWmC,EAAAA,aAAAA;wBACXI,GAAK,EAAA,CAAC,QAAQ,EAAEC,OAAS,CAAA,CAAA;wBACzBvB,SAAW6B,EAAAA;AACb,qBAAA;oBACAhD,IAAM,EAAA;AACJoC,wBAAAA,KAAAA;wBACAlC,SAAWmC,EAAAA,aAAAA;wBACXI,GAAK,EAAA,CAAC,QAAQ,EAAEC,OAAS,CAAA,CAAA;wBACzBvB,SAAW8B,EAAAA;AACb;AACF,iBAAA,CAAA;AACF;AACF;AACF,KAAA,CAAA;IAEA,OAAOxD,KAAAA;AACT,CAAA;;;;"}