{"version":3,"file":"restore.mjs","sources":["../../../../../src/cli/commands/configuration/restore.ts"],"sourcesContent":["import { createCommand } from 'commander';\nimport fs from 'fs';\nimport _ from 'lodash';\nimport { createStrapi, compileStrapi } from '@strapi/core';\nimport type { Database } from '@strapi/database';\n\nimport type { StrapiCommand } from '../../types';\nimport { runAction } from '../../utils/helpers';\n\ntype Strategy = 'replace' | 'merge' | 'keep';\n\ninterface CmdOptions {\n  file?: string;\n  strategy?: Strategy;\n}\n\n/**\n * Will restore configurations. It reads from a file or stdin\n */\nconst action = async ({ file: filePath, strategy = 'replace' }: CmdOptions) => {\n  const input = filePath ? fs.readFileSync(filePath) : await readStdin();\n\n  const appContext = await compileStrapi();\n  const app = await createStrapi(appContext).load();\n\n  let dataToImport;\n  try {\n    dataToImport = JSON.parse(_.toString(input));\n  } catch (error) {\n    if (error instanceof Error) {\n      throw new Error(`Invalid input data: ${error.message}. Expected a valid JSON array.`);\n    }\n\n    throw error;\n  }\n\n  if (!Array.isArray(dataToImport)) {\n    throw new Error(`Invalid input data. Expected a valid JSON array.`);\n  }\n\n  if (!app.db) {\n    throw new Error('Cannot import configuration without a database connection.');\n  }\n\n  const importer = createImporter(app.db, strategy);\n\n  for (const config of dataToImport) {\n    await importer.import(config);\n  }\n\n  console.log(\n    `Successfully imported configuration with ${strategy} strategy. Statistics: ${importer.printStatistics()}.`\n  );\n\n  process.exit(0);\n};\n\nconst readStdin = () => {\n  const { stdin } = process;\n  let result = '';\n\n  if (stdin.isTTY) return Promise.resolve(result);\n\n  return new Promise((resolve, reject) => {\n    stdin.setEncoding('utf8');\n    stdin.on('readable', () => {\n      let chunk;\n      // eslint-disable-next-line no-cond-assign\n      while ((chunk = stdin.read())) {\n        result += chunk;\n      }\n    });\n\n    stdin.on('end', () => {\n      resolve(result);\n    });\n\n    stdin.on('error', reject);\n  });\n};\n\nconst createImporter = (db: Database, strategy?: Strategy) => {\n  switch (strategy) {\n    case 'replace':\n      return createReplaceImporter(db);\n    case 'merge':\n      return createMergeImporter(db);\n    case 'keep':\n      return createKeepImporter(db);\n    default:\n      throw new Error(`No importer available for strategy \"${strategy}\"`);\n  }\n};\n\n/**\n * Replace importer. Will replace the keys that already exist and create the new ones\n */\nconst createReplaceImporter = (db: Database) => {\n  const stats = {\n    created: 0,\n    replaced: 0,\n  };\n\n  return {\n    printStatistics() {\n      return `${stats.created} created, ${stats.replaced} replaced`;\n    },\n\n    async import(conf: Record<string, unknown>) {\n      const matching = await db.query('strapi::core-store').count({ where: { key: conf.key } });\n      if (matching > 0) {\n        stats.replaced += 1;\n        await db.query('strapi::core-store').update({\n          where: { key: conf.key },\n          data: conf,\n        });\n      } else {\n        stats.created += 1;\n        await db.query('strapi::core-store').create({ data: conf });\n      }\n    },\n  };\n};\n\n/**\n * Merge importer. Will merge the keys that already exist with their new value and create the new ones\n */\nconst createMergeImporter = (db: Database) => {\n  const stats = {\n    created: 0,\n    merged: 0,\n  };\n\n  return {\n    printStatistics() {\n      return `${stats.created} created, ${stats.merged} merged`;\n    },\n\n    async import(conf: Record<string, unknown>) {\n      const existingConf = await db\n        .query('strapi::core-store')\n        .findOne({ where: { key: conf.key } });\n\n      if (existingConf) {\n        stats.merged += 1;\n        await db.query('strapi::core-store').update({\n          where: { key: conf.key },\n          data: _.merge(existingConf, conf),\n        });\n      } else {\n        stats.created += 1;\n        await db.query('strapi::core-store').create({ data: conf });\n      }\n    },\n  };\n};\n\n/**\n * Merge importer. Will keep the keys that already exist without changing them and create the new ones\n */\nconst createKeepImporter = (db: Database) => {\n  const stats = {\n    created: 0,\n    untouched: 0,\n  };\n\n  return {\n    printStatistics() {\n      return `${stats.created} created, ${stats.untouched} untouched`;\n    },\n\n    async import(conf: Record<string, unknown>) {\n      const matching = await db.query('strapi::core-store').count({ where: { key: conf.key } });\n      if (matching > 0) {\n        stats.untouched += 1;\n        // if configuration already exists do not overwrite it\n        return;\n      }\n\n      stats.created += 1;\n      await db.query('strapi::core-store').create({ data: conf });\n    },\n  };\n};\n\n/**\n * `$ strapi configuration:restore`\n */\nconst command: StrapiCommand = () => {\n  return createCommand('configuration:restore')\n    .alias('config:restore')\n    .description('Restore configurations of your application')\n    .option('-f, --file <file>', 'Input file, default input is stdin')\n    .option('-s, --strategy <strategy>', 'Strategy name, one of: \"replace\", \"merge\", \"keep\"')\n    .action(runAction('configuration:restore', action));\n};\n\nexport { action, command };\n"],"names":["action","file","filePath","strategy","input","fs","readFileSync","readStdin","appContext","compileStrapi","app","createStrapi","load","dataToImport","JSON","parse","_","toString","error","Error","message","Array","isArray","db","importer","createImporter","config","import","console","log","printStatistics","process","exit","stdin","result","isTTY","Promise","resolve","reject","setEncoding","on","chunk","read","createReplaceImporter","createMergeImporter","createKeepImporter","stats","created","replaced","conf","matching","query","count","where","key","update","data","create","merged","existingConf","findOne","merge","untouched","command","createCommand","alias","description","option","runAction"],"mappings":"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"}