{"version":3,"file":"App-DYSHgaC_.mjs","sources":["../../admin/src/utils/export-utils.ts","../../admin/src/utils/import-export-utils.ts","../../admin/src/pages/Export.tsx","../../admin/src/pages/Header.tsx","../../admin/src/pages/Import.tsx","../../admin/src/pages/Output.tsx","../../admin/src/pages/HomePage.tsx","../../admin/src/pages/App.tsx"],"sourcesContent":["const SYSTEM_FIELDS = [\n  \"id\", \"createdAt\", \"created_at\", \"updatedAt\", \"updated_at\", \"publishedAt\", \"published_at\"\n];\n\nexport function stripUnsafeFields(obj: any): any {\n  const res: any = {};\n  for (const key in obj) {\n    if (!SYSTEM_FIELDS.includes(key)) {\n      res[key] = obj[key];\n    }\n  }\n  return res;\n}\n\n// CSV парсер с учётом кавычек\nexport function csvToJson(csvString: string, delimiter: string = \",\"): any[] {\n  let csv = csvString.replace(/^\\uFEFF/, '').trim();\n  let lines = csv.split(/\\r?\\n/).filter(Boolean);\n  if (lines.length < 2) return [];\n  // Продвинутый split с учётом кавычек\n  const splitCsvRow = (row: string) => {\n    const re = new RegExp(\n      `\\\\s*(?:(?:\"([^\"]*(?:\"\"[^\"]*)*)\")|([^\"${delimiter}]+))\\\\s*(?:${delimiter}|$)`,\n      \"g\"\n    );\n    const result = [];\n    let match;\n    let lastIndex = 0;\n    while ((match = re.exec(row)) !== null && lastIndex < row.length) {\n      lastIndex = re.lastIndex;\n      result.push(match[1] !== undefined ? match[1].replace(/\"\"/g, '\"') : match[2]);\n    }\n    return result;\n  };\n  const header = splitCsvRow(lines[0]).map(h => h.trim());\n  return lines.slice(1).map(line => {\n    const values = splitCsvRow(line);\n    const obj: any = {};\n    header.forEach((key, i) => {\n      obj[key] = values[i] ?? \"\";\n    });\n    return obj;\n  });\n}\n\nexport function jsonToCsv(items: any[]): string {\n  if (!items.length) return \"\";\n  const replacer = (_: string, value: any) =>\n    value === null || value === undefined ? \"\" : value;\n  const header = Object.keys(items[0]);\n  const csv = [\n    header.join(\",\"),\n    ...items.map((row) =>\n      header.map((fieldName) => JSON.stringify(row[fieldName], replacer)).join(\",\")\n    ),\n  ].join(\"\\r\\n\");\n  return csv;\n}\n\nexport function downloadAsFile({\n                                 data,\n                                 fileName,\n                                 mime,\n                               }: {\n  data: string;\n  fileName: string;\n  mime: string;\n}) {\n  const blob = new Blob([data], {type: mime});\n  const url = URL.createObjectURL(blob);\n  const link = document.createElement(\"a\");\n  link.href = url;\n  link.setAttribute(\"download\", fileName);\n  document.body.appendChild(link);\n  link.click();\n  document.body.removeChild(link);\n  URL.revokeObjectURL(url);\n}\n","// tablify/admin/src/utils/import-export-logic.ts\n\nimport {csvToJson, downloadAsFile, jsonToCsv} from \"./export-utils\";\n\n// System fields to exclude from user operations\nexport const SYSTEM_FIELDS = [\n  \"id\",\n  \"createdAt\",\n  \"created_at\",\n  \"updatedAt\",\n  \"updated_at\",\n  \"publishedAt\",\n  \"published_at\",\n];\n\n// Normalizes value based on the schema field type\nexport function normalizeValueByType(value: any, type: string) {\n  if (\n    value === \"\" ||\n    value === null ||\n    value === undefined ||\n    value === \"undefined\"\n  ) {\n    return null;\n  }\n  switch (type) {\n    case \"integer\":\n    case \"biginteger\":\n    case \"float\":\n    case \"decimal\": {\n      const n = Number(value);\n      return isNaN(n) ? null : n;\n    }\n    case \"boolean\":\n      if (typeof value === \"boolean\") return value;\n      if (value === \"true\" || value === true || value === 1 || value === \"1\") return true;\n      if (value === \"false\" || value === false || value === 0 || value === \"0\") return false;\n      return null;\n    case \"date\":\n    case \"datetime\":\n    case \"timestamp\":\n      // Accept ISO date strings, otherwise null\n      if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}/.test(value)) return value;\n      return null;\n    default:\n      return value;\n  }\n}\n\n// Returns a new object containing only fields defined in the schema, normalized\nexport function stripAndNormalizeBySchema(obj: any, schema: any): any {\n  const result: any = {};\n  for (const key in schema) {\n    if (!SYSTEM_FIELDS.includes(key)) {\n      if (Object.prototype.hasOwnProperty.call(obj, key)) {\n        result[key] = normalizeValueByType(obj[key], schema[key].type);\n      }\n    }\n  }\n  return result;\n}\n\n// Handles exporting the selected table as JSON or CSV\nexport async function handleDownload({\n                                       type,\n                                       selected,\n                                       getSelectedTable,\n                                     }: {\n  type: \"json\" | \"csv\";\n  selected: string | undefined;\n  getSelectedTable: () => any;\n}) {\n  if (!selected) return;\n  const table = getSelectedTable();\n  if (!table) return;\n\n  const res = await fetch(\"/strapi-plugin-tablify/dump-collection\", {\n    method: \"POST\",\n    headers: {\"Content-Type\": \"application/json\"},\n    body: JSON.stringify({name: table.tableName}),\n  });\n\n  if (!res.ok) throw new Error(\"Failed to fetch data from the server.\");\n  const {data} = await res.json();\n\n  if (type === \"json\") {\n    downloadAsFile({\n      data: JSON.stringify(data, null, 2),\n      fileName: `${table.tableName}.json`,\n      mime: \"application/json\",\n    });\n  } else if (type === \"csv\") {\n    const csv = jsonToCsv(data);\n    downloadAsFile({\n      data: csv,\n      fileName: `${table.tableName}.csv`,\n      mime: \"text/csv;charset=utf-8;\",\n    });\n  }\n}\n\n// Handles importing a file (JSON or CSV) into the selected table\nexport async function importFile({\n                                   file,\n                                   tableName,\n                                   tableSchema,\n                                   csvDelimiter,\n                                 }: {\n  file: File;\n  tableName: string;\n  tableSchema: any;\n  csvDelimiter: string;\n}): Promise<{ log: string; debug: string }> {\n  let debug = \"\";\n  let log = \"\";\n  let records: any[] = [];\n\n  debug += `File name: ${file.name}\\nFile size: ${file.size} bytes\\n`;\n  const text = await file.text();\n  debug += `First 1kB of file:\\n${text.slice(0, 1000)}\\n`;\n\n  const fileName = file.name.toLowerCase();\n\n  // Detect file format by extension or content\n  let format: \"json\" | \"csv\" = \"json\";\n  if (fileName.endsWith(\".csv\")) format = \"csv\";\n  else if (fileName.endsWith(\".json\")) format = \"json\";\n  else {\n    if (text.trim().startsWith(\"{\") || text.trim().startsWith(\"[\")) format = \"json\";\n    else format = \"csv\";\n  }\n  debug += `Detected format: ${format}\\n`;\n\n  try {\n    if (format === \"json\") {\n      records = JSON.parse(text);\n      debug += `JSON parsed successfully. Type: ${Array.isArray(records) ? \"array\" : typeof records}\\n`;\n      if (!Array.isArray(records)) throw new Error(\"JSON file must be an array of objects.\");\n    } else if (format === \"csv\") {\n      debug += `CSV delimiter: \"${csvDelimiter || \",\"}\"\\n`;\n      const lines = text.replace(/^\\uFEFF/, \"\").trim().split(/\\r?\\n/).filter(Boolean);\n      debug += `CSV row count: ${lines.length}\\n`;\n      debug += `Header: ${lines[0]}\\n`;\n      if (lines.length > 1) debug += `First data row: ${lines[1]}\\n`;\n      records = csvToJson(text, csvDelimiter || \",\");\n      debug += `CSV parsed successfully. Number of objects: ${records.length}\\n`;\n      if (records.length > 0) {\n        debug += `First object: ${JSON.stringify(records[0], null, 2)}\\n`;\n      }\n    }\n    if (!records.length) {\n      log = \"No data found in the file to import.\";\n      debug += log + \"\\n\";\n      return {log, debug};\n    }\n  } catch (e: any) {\n    log = \"Parsing error: \" + (e.message || e);\n    debug += log + \"\\n\";\n    return {log, debug};\n  }\n\n  // Strip unwanted fields and normalize values according to schema\n  records = records.map((row) => stripAndNormalizeBySchema(row, tableSchema));\n\n  debug += `Prepared for upload: ${records.length} objects\\n`;\n\n  try {\n    const res = await fetch(\"/strapi-plugin-tablify/import-collection\", {\n      method: \"POST\",\n      headers: {\"Content-Type\": \"application/json\"},\n      body: JSON.stringify({\n        name: tableName,\n        data: records,\n        format,\n      }),\n    });\n    const result = await res.json();\n    debug += `Server response: ${JSON.stringify(result, null, 2)}\\n`;\n    if (result.success) {\n      log = `Import complete: ${result.created} records added, ${result.failed} errors.`;\n      if (result.failedDetails && result.failedDetails.length) {\n        log += \"\\nErrors:\\n\" + result.failedDetails.join(\"\\n\");\n      }\n    } else {\n      log = \"Import failed: \" + (result.message || \"Unknown server error.\");\n    }\n  } catch (e: any) {\n    log = \"Import error: \" + (e.message || e);\n    debug += log + \"\\n\";\n  }\n  return {log, debug};\n}\n\n// Don't forget to export stripAndNormalizeBySchema if used elsewhere.\n","import {Box, Button, SingleSelect, SingleSelectOption, Typography} from \"@strapi/design-system\";\nimport React from \"react\";\n\ninterface Props {\n  selected: string | undefined\n  setSelected: (s: string | undefined) => void\n  tables: { uid: string; tableName: string; displayName: string }[]\n  onDownload: (type: \"json\" | \"csv\") => void\n  downloading: \"csv\" | \"json\" | false\n}\n\nexport const Export = (props: Props) => {\n\n  console.log(\"+++props?.tables\", props?.tables)\n\n  return <Box marginBottom={6}>\n\n    <Box marginBottom={2}>\n      <Typography variant=\"delta\" as=\"h4\">\n        Export\n      </Typography>\n    </Box>\n\n    <Box marginBottom={4}>\n      <SingleSelect\n        label=\"Tables\"\n        placeholder=\"Select a table\"\n        value={props.selected}\n        onChange={props.setSelected}\n      >\n        {props?.tables?.map((table) => (\n          <SingleSelectOption key={table.uid} value={table.uid}>\n            {`${table.displayName} (${table.tableName})`}\n          </SingleSelectOption>\n        ))}\n      </SingleSelect>\n    </Box>\n\n    <Box display=\"flex\">\n      <Button\n        style={{marginRight: 10}}\n        size={3}\n        onClick={() => props.onDownload(\"json\")}\n        disabled={!props.selected || props.downloading === \"json\"}\n        loading={props.downloading === \"json\"}\n        variant=\"default\"\n      >\n        Download JSON\n      </Button>\n      <Button\n        style={{marginRight: 10}}\n        onClick={() => props.onDownload(\"csv\")}\n        disabled={!props.selected || props.downloading === \"csv\"}\n        loading={props.downloading === \"csv\"}\n        variant=\"default\"\n      >\n        Download CSV\n      </Button>\n\n    </Box>\n\n  </Box>\n\n}\n","import {Box, Typography} from \"@strapi/design-system\";\nimport React from \"react\";\n\nexport const Header = () => {\n  return (\n    <Box marginBottom={4}>\n      <Typography variant=\"alpha\" as=\"h1\">\n        Import & Export Data\n      </Typography>\n      <Typography variant=\"epsilon\" as=\"p\">\n        Select a collection to import data from CSV or JSON, or export your data in one click.\n      </Typography>\n    </Box>\n  );\n};\n","import {Box, Button, Flex, TextInput, Typography} from \"@strapi/design-system\";\nimport React from \"react\";\n\ninterface Props {\n  csvDelimiter: string\n  setCsvDelimiter: (newCsvDelimiter: string) => void;\n  fileInputRef: any\n  handleFileChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n  onImport: () => void;\n  fileName: string\n  selected: string | undefined\n  importing: boolean\n}\n\nexport const Import = (props: Props) => {\n  return <Box marginBottom={6}>\n    <Box marginBottom={2}>\n      <Typography variant=\"delta\" as=\"h4\">\n        Import\n      </Typography>\n    </Box>\n    <Box marginBottom={4}>\n      <Flex alignItems=\"center\">\n        <TextInput\n          style={{width: 50, marginRight: 10}}\n          size=\"S\"\n          label=\"CSV delimiter (default is comma)\"\n          placeholder=\"Enter delimiter\"\n          name=\"csv-delimiter\"\n          value={props.csvDelimiter}\n          onChange={(e: any) => props.setCsvDelimiter(e.target.value)}\n          hint=\"For example: , ; | \\t\"\n        />\n        <Typography variant=\"omega\" style={{marginLeft: 10}}>\n          Character that separates values in your CSV file.\n          Examples: comma (,), semicolon (;), tab (\\t)\n        </Typography>\n      </Flex>\n    </Box>\n    <input\n      type=\"file\"\n      accept=\".json,.csv\"\n      ref={props.fileInputRef}\n      style={{display: \"none\"}}\n      onChange={props.handleFileChange}\n    />\n    <Flex alignItems=\"center\">\n      <Button\n        variant=\"default\"\n        style={{marginRight: 10}}\n        onClick={() => props.fileInputRef?.current?.click()}\n      >\n        {props.fileName ? \"Change file\" : \"Select file\"}\n      </Button>\n      <Button\n        disabled={!props.selected || props.importing || !props.fileName}\n        loading={props.importing}\n        variant=\"default\"\n        onClick={props.onImport}\n      >\n        Import\n      </Button>\n    </Flex>\n    <Box>\n    </Box>\n  </Box>\n}\n","import {Box, Typography} from \"@strapi/design-system\";\nimport React from \"react\";\n\ninterface Props {\n  debugLog: string\n  importLog: string\n}\n\nexport const Output = (props: Props) => {\n  return <Box marginTop={8}>\n    <Box marginBottom={2}>\n      <Typography variant=\"delta\" as=\"h4\">\n        Output:\n      </Typography>\n    </Box>\n    {props.importLog && <Box background=\"neutral100\" hasRadius padding={4}>\n      {props.importLog && (\n        <Box marginTop={4}>\n          <Typography\n            variant=\"omega\"\n            textColor=\"danger600\"\n            as=\"pre\"\n            style={{whiteSpace: \"pre-line\"}}\n          >\n            {props.importLog}\n          </Typography>\n        </Box>\n      )}\n      {props.debugLog && (\n        <Box marginTop={4}>\n          <Typography\n            variant=\"omega\"\n            textColor=\"primary600\"\n            as=\"pre\"\n            style={{whiteSpace: \"pre-line\", fontSize: 11}}\n          >\n            {props.debugLog}\n          </Typography>\n        </Box>\n      )}\n    </Box>}\n  </Box>\n}\n","import {Box, Main,} from \"@strapi/design-system\";\nimport React, {useEffect, useRef, useState} from \"react\";\nimport {handleDownload, importFile} from \"./../utils/import-export-utils\";\nimport {Export} from \"./Export\";\nimport {Header} from \"./Header\";\nimport {Import} from \"./Import\";\nimport {Output} from \"./Output\";\n\nexport const HomePage = () => {\n  const [tables, setTables] = useState<\n    { uid: string; tableName: string; displayName: string }[]\n  >([]);\n  const [selected, setSelected] = useState<string | undefined>(undefined);\n  const [downloading, setDownloading] = useState<\"csv\" | \"json\" | false>(false);\n  const [importing, setImporting] = useState(false);\n  const [importLog, setImportLog] = useState<string>(\"\");\n  const [csvDelimiter, setCsvDelimiter] = useState<string>(\",\");\n  const [debugLog, setDebugLog] = useState<string>(\"\");\n  const fileInputRef = useRef<HTMLInputElement>(null);\n  const [tableSchema, setTableSchema] = useState<any>(null);\n  const [fileName, setFileName] = useState<string>(\"\");\n\n  useEffect(() => {\n    fetch(\"/tablify/tables\")\n      .then((res) => res.json())\n      .then((data) => setTables(data))\n      .catch(() => setTables([]));\n  }, []);\n\n  useEffect(() => {\n    if (selected) {\n      fetch(`/tablify/schema?uid=${encodeURIComponent(selected)}`)\n        .then((res) => res.json())\n        .then(setTableSchema)\n        .catch(() => setTableSchema(null));\n    } else {\n      setTableSchema(null);\n    }\n  }, [selected]);\n\n  const getSelectedTable = () => tables.find((t) => t.uid === selected);\n\n  const onDownload = async (type: \"json\" | \"csv\") => {\n    setDownloading(type);\n    try {\n      await handleDownload({\n        type,\n        selected,\n        getSelectedTable,\n      });\n    } catch (e: any) {\n      alert(\"Download failed: \" + (e.message || e));\n    }\n    setDownloading(false);\n  };\n\n  const onImport = async () => {\n    setImportLog(\"\");\n    setDebugLog(\"\");\n    if (!selected || !fileInputRef.current?.files?.length) {\n      setDebugLog(\"Нет выбранной таблицы или файла.\");\n      return;\n    }\n    setImporting(true);\n    try {\n      const file = fileInputRef.current.files[0];\n      const table = getSelectedTable();\n      if (!table) throw new Error(\"Table not found\");\n      const {log, debug} = await importFile({\n        file,\n        tableName: table.tableName,\n        tableSchema,\n        csvDelimiter,\n      });\n      setImportLog(log);\n      setDebugLog(debug);\n    } catch (e: any) {\n      setImportLog(\"Import error: \" + (e.message || e));\n      setDebugLog(String(e));\n    }\n    setImporting(false);\n    if (fileInputRef.current) {\n      fileInputRef.current.value = \"\";\n      setFileName(\"\");\n    }\n  };\n\n  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    if (e.target.files?.length) {\n      setFileName(e.target.files[0].name);\n    } else {\n      setFileName(\"\");\n    }\n  };\n\n  return (\n    <Main>\n\n      <Box padding={8} background=\"neutral0\" shadow=\"tableShadow\" hasRadius>\n\n        <Header/>\n\n        <Export\n          tables={tables}\n          selected={selected}\n          setSelected={setSelected}\n          onDownload={onDownload}\n          downloading={downloading}/>\n\n        <Import\n          selected={selected}\n          csvDelimiter={csvDelimiter}\n          setCsvDelimiter={setCsvDelimiter}\n          fileInputRef={fileInputRef}\n          handleFileChange={handleFileChange}\n          onImport={onImport}\n          fileName={fileName}\n          importing={importing}/>\n\n        <Output debugLog={debugLog} importLog={importLog}/>\n\n      </Box>\n\n    </Main>\n  );\n};\n","import {Page} from '@strapi/strapi/admin';\nimport {Route, Routes} from 'react-router-dom';\n\nimport {HomePage} from './HomePage';\n\nconst App = () => {\n  return (\n    <Routes>\n      <Route index element={<HomePage/>}/>\n      <Route path=\"*\" element={<Page.Error/>}/>\n    </Routes>\n  );\n};\n\nexport {App};\n"],"names":[],"mappings":"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"}