{"version":3,"file":"api-handler.mjs","sources":["../../../server/src/services/api-handler.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fse from 'fs-extra';\nimport type { Internal } from '@strapi/types';\n\n/**\n * Deletes the API folder of a contentType\n */\nexport async function clear(uid: Internal.UID.ContentType) {\n // TODO double check if this is the correct way to get the apiName\n const { apiName, modelName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n\n await recursiveRemoveFiles(apiFolder, createDeleteApiFunction(modelName));\n await deleteBackup(uid);\n}\n\n/**\n * Backups the API folder of a contentType\n * @param {string} uid content type uid\n */\nexport async function backup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n // backup the api folder\n await fse.copy(apiFolder, backupFolder);\n}\n\n/**\n * Deletes an API backup folder\n */\nasync function deleteBackup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const backupFolder = path.join(strapi.dirs.app.api, '.backup');\n const apiBackupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n await fse.remove(apiBackupFolder);\n\n const list = await fse.readdir(backupFolder);\n if (list.length === 0) {\n await fse.remove(backupFolder);\n }\n}\n\n/**\n * Rollbacks the API folder of a contentType\n */\nexport async function rollback(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n try {\n await fse.access(backupFolder);\n } catch {\n throw new Error('Cannot rollback api that was not backed up');\n }\n\n await fse.remove(apiFolder);\n await fse.copy(backupFolder, apiFolder);\n await deleteBackup(uid);\n}\n\n/**\n * Creates a delete function to clear an api folder\n */\nconst createDeleteApiFunction = (baseName: string) => {\n /**\n * Delets a file in an api.\n * Will only update routes.json instead of deleting it if other routes are present\n */\n return async (filePath: string) => {\n const fileName = path.basename(filePath, path.extname(filePath));\n\n const isSchemaFile = filePath.endsWith(`${baseName}/schema.json`);\n if (fileName === baseName || isSchemaFile) {\n return fse.remove(filePath);\n }\n };\n};\n\n/**\n * Deletes a folder recursively using a delete function\n * @param {string} folder folder to delete\n */\nconst recursiveRemoveFiles = async (\n folder: string,\n deleteFn: (file: string) => unknown\n): Promise => {\n const filesName = await fse.readdir(folder);\n\n for (const fileName of filesName) {\n const filePath = path.join(folder, fileName);\n\n const stat = await fse.stat(filePath);\n\n if (stat.isDirectory()) {\n await recursiveRemoveFiles(filePath, deleteFn);\n } else {\n await deleteFn(filePath);\n }\n }\n\n const files = await fse.readdir(folder);\n if (files.length === 0) {\n await fse.remove(folder);\n }\n};\n"],"names":["clear","uid","apiName","modelName","strapi","contentTypes","apiFolder","path","join","dirs","app","api","recursiveRemoveFiles","createDeleteApiFunction","deleteBackup","backup","backupFolder","fse","copy","apiBackupFolder","remove","list","readdir","length","rollback","access","Error","baseName","filePath","fileName","basename","extname","isSchemaFile","endsWith","folder","deleteFn","filesName","stat","isDirectory","files"],"mappings":"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"}